「foo」、「bar」、および「baz」という単語をすべて含むmanページを検索します


12

「foo」、「bar」、および「baz」という単語をすべて含むmanページを検索したい。

可能であれば、すべてのmanページのすべてのテキスト(名前と説明だけでなく)を検索したいと思います。

私は次のようなものを推測しています

man -K foo AND bar AND baz

スクリプトは機能しましたか?uはフィードバックをしませんでした:)
polym 14年

回答:


5

まさにこれを行うスクリプトを実装しました。

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

時間の無駄だと思います:(

編集:のようです

man -K expr1 expr2 expr3

うまくいかなかった?

編集:スクリプトを検索キーワードとして渡すことができます ./script foo bar


結局のところ、スクリプトが唯一の方法のように見えます。
グレアム14年

2
奇妙なしかし、真^ ^ -しかし、それはのために投票に楽しかった時間の無駄 ...
mikeserv

異なる引数を使用するだけでorand適切にテストしなかったからだと思っただけです。
グレアム14年

3

スクリプトの作成に関するいくつかの考え:

  • を使用manpathして、manページの場所を取得します。に追加/home/graeme/.cabal/binするとPATHmanpath(およびman)でmanページが見つかります/home/graeme/.cabal/share/manます。

  • 検索する前にページ自体を解凍してフォーマットするためにmanを使用します。この方法では、rawファイル内のコメントなどではなく、manテキスト自体を検索するだけです。を使用manすると、複数の形式が処理される可能性があります。

  • フォーマットされたページを一時ファイルに保存すると、複数の圧縮解除が回避され、処理速度が大幅に向上します。

ここに(bashGNU findで)行きます:

#!/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の答えほど完全ではありませんが、私は次のようなものを提案するつもりでした

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)

-w(単語一致)スイッチを追加したことに注意してくださいgreps-これはあなたが望むものではないかもしれません(foo lishやnut barのような一致を含めたいですか?)


とても礼儀正しくお願いします。
mikeserv 14年

0

このアプローチはテストされていませんが、かなりシンプル(愚かなシンプル)であり、非効率であっても機能するはずです。

#!/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[@]}"
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.