Cari halaman manual yang berisi SEMUA kata 'foo' 'bar' dan 'baz'


12

Saya ingin mencari halaman manual yang berisi SEMUA kata 'foo', 'bar' dan 'baz'.

Jika memungkinkan, saya ingin mencari melalui semua teks (bukan hanya nama & deskripsi) dari semua halaman manual.

Saya kira sesuatu seperti

man -K foo AND bar AND baz

apakah skrip saya berfungsi? kamu tidak memberikan umpan balik :)
polym

Jawaban:


5

Saya menerapkan skrip yang melakukan hal ini.

if [ $# -eq 0 ]; then
  PATTERNS=(NAME AUTHOR EXAMPLES FILES)
else
  PATTERNS=( "$@" )
fi

[ ${#PATTERNS[@]} -lt 1 ] && echo "Needs at least 1 pattern to search for" && exit 1

for i in $(find /usr/share/man/ -type f); do
  TMPOUT=$(zgrep -l "${PATTERNS[0]}" "$i")
  [ -z "$TMPOUT" ] && continue

  for c in `seq 1 $((${#PATTERNS[@]}-1))`; do
    TMPOUT=$(echo "$TMPOUT" | xargs zgrep -l "${PATTERNS[$c]}")
    [ -z "$TMPOUT" ] && break
  done

  if [ ! -z "$TMPOUT" ]; then
    #echo "$TMPOUT" # Prints the whole path
    MANNAME="$(basename "$TMPOUT")"
    man "${MANNAME%%.*}"
  fi
done

Kira itu buang-buang waktu :(

Sunting: Sepertinya

man -K expr1 expr2 expr3

tidak bekerja?

Sunting: Anda dapat melewati skrip sekarang dengan menggunakan istilah pencarian Anda ./script foo bar


Sepertinya skrip adalah satu-satunya cara.
Graeme

2
Aneh tapi ^ benar ^ - tapi itu menyenangkan untuk memilih buang - buang waktu ...
mikeserv

Hanya dengan menggunakan argumen yang berbeda or, saya hanya berpikir itu andkarena saya tidak mengujinya dengan benar.
Graeme

3

Beberapa pemikiran tentang penulisan skrip ini:

  • Menggunakan manpathuntuk mendapatkan lokasi halaman manual. Jika saya menambahkan /home/graeme/.cabal/binke saya PATH, manpath(dan man) akan menemukan halaman manual di /home/graeme/.cabal/share/man.

  • Gunakan man itu sendiri untuk mendekompresi dan memformat halaman sebelum mencari, dengan cara ini Anda hanya mencari teks man itu sendiri dan tidak ada komentar dll dalam file mentah. Menggunakan manakan berpotensi menangani berbagai format.

  • Menyimpan halaman yang diformat dalam tempfile akan menghindari beberapa dekompresi dan harus mempercepatnya secara signifikan.

Ini dia (dengan bashdan GNU temukan):

#!/bin/bash

set -f; IFS=:
trap 'rm -f "$temp"' EXIT
temp=$(mktemp --tmpdir search_man.XXXXXXXXXX)

while IFS= read -rd '' file; do
  man "$file" >"$temp" 2>/dev/null

  unset fail
  for arg; do
    if ! grep -Fq -- "$arg" "$temp"; then
      fail=true
      break
    fi
  done

  if [ -z "$fail" ]; then
    file=${file##*/}
    printf '%s\n' "${file%.gz}"
  fi
done < <(find $(manpath) -type d ! -name 'man*' -prune -o -type f -print0)

2

Tidak selengkap jawaban @ polym, tapi saya akan menyarankan sesuatu seperti

while IFS= read -rd $'\0' f; do 
  zgrep -qwm1 'foo' "$f" && \
  zgrep -qwm1 'bar' "$f" && \
  zgrep -qwm1 'baz' "$f" && \
  printf '%s\n' "$f"
done < <(find /usr/share/man -name '*.gz' -print0)

Perhatikan bahwa saya menambahkan -w(pencocokan kata) ke greps- yang mungkin bukan yang Anda inginkan (Anda ingin memasukkan kecocokan seperti foo lish dan bilah kacang ?)


Anda sangat sopan untuk bertanya.
mikeserv

0

Pendekatan ini tidak teruji tetapi cukup sederhana (bodoh sederhana) dan saya berharap itu akan berhasil, bahkan jika tidak efisien:

#!/bin/bash

if [ "$#" -eq 0 ]; then
  echo "Provide arguments to search all man pages for all arguments." >&2
  echo "Putting rare search terms first will improve performance." >&2
  exit
fi

if [ "$#" -eq 1 ]; then
  exec man -K "$@"
fi

pages=( $(man -wK "$1") )
shift
while [ "$#" -gt 1 ]; do
  pages=( $(zgrep -l "$1" "${pages[@]}") )
  shift
done
exec man "${pages[@]}"
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.