TÜM 'foo' 'bar' ve 'baz' kelimelerini içeren adam sayfalarını arayın


12

TÜM 'foo', 'bar' ve 'baz' kelimelerini içeren adam sayfalarını aramak istiyorum.

Mümkünse, tüm sayfaların tüm metninde (yalnızca ad ve açıklama değil) arama yapmak istiyorum.

Gibi bir şey tahmin ediyorum

man -K foo AND bar AND baz

senaryom çalıştı mı? u geri bildirimde bulunmadı :)
Polym

Yanıtlar:


5

Tam olarak bunu yapan bir komut dosyası uyguladım.

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

Sanırım zaman kaybı oldu :(

Düzenleme: Görünüşe göre

man -K expr1 expr2 expr3

çalışmadı mı?

Düzenle: Komut dosyalarını artık arama terimlerinizi ./script foo bar


Her şeyden önce bir komut dosyası gibi görünüyor.
Graeme

2
Garip ama ^ doğru ^ - ama zaman kaybı için oy vermek eğlenceliydi ...
mikeserv

Farklı argümanlar kullanarak or, sadece anddoğru test etmediğim için olduğunu düşündüm .
Graeme

3

Bu senaryoyu yazmayla ilgili birkaç düşünce:

  • manpathMan sayfalarının konumlarını almak için kullanma . Eğer /home/graeme/.cabal/bineklersem PATH, manpath(ve man) içinde man sayfaları bulur /home/graeme/.cabal/share/man.

  • Aramadan önce sayfaları açmak ve biçimlendirmek için insanın kendisini kullanın, bu şekilde ham dosyadaki herhangi bir yorum vb. Kullanmak manpotansiyel olarak birden fazla formatla ilgilenecektir.

  • Biçimlendirilmiş sayfaları geçici bir dosyaya kaydetmek, birden fazla sıkıştırmayı önler ve işleri önemli ölçüde hızlandırır.

İşte ( bashGNU find ile birlikte ):

#!/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

@ Polym'nin cevabı kadar eksiksiz değil, ama böyle bir şey önerecektim

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)

İstediğiniz olmayabilir - -w(kelime eşleme) anahtarını eklediğimi unutmayın ( foo lish ve nut bargreps gibi eşleşmeleri eklemek ister misiniz ?)


Sormanız çok kibar.
mikeserv

0

Bu yaklaşım test edilmemiştir, ancak oldukça basittir (aptalca basit) ve verimsiz olsa bile çalışmasını bekliyorum:

#!/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[@]}"
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.