
我想搜尋包含所有單字「foo」、「bar」和「baz」的手冊頁。
如果可能的話,我想搜尋所有手冊頁的所有文字(不僅僅是名稱和描述)。
我猜是這樣的
man -K foo AND bar AND baz
答案1
我實作了一個腳本來完成這個任務。
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
答案2
關於編寫此腳本的一些想法:
用於
manpath
取得手冊頁的位置。如果我添加/home/graeme/.cabal/bin
到我的PATH
,manpath
(並且man
) 將在 中找到手冊頁/home/graeme/.cabal/share/man
。在搜尋之前使用 man 本身來解壓縮和格式化頁面,這樣您只需搜尋 man 文字本身,而不是原始文件中的任何註釋等。使用
man
可能會處理多種格式。將格式化的頁面儲存在暫存檔案中將避免多次解壓縮,並且會顯著加快速度。
如下(使用bash
GNU 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)
答案3
不像@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
這可能不是您想要的(您想包含像這樣的匹配嗎?富利甚和堅果酒吧?
答案4
這種方法未經測試,但相當簡單(愚蠢的簡單),我希望它應該有效,即使效率低下:
#!/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[@]}"