
Ich möchte nach Manpages suchen, die ALLE Wörter „foo“, „bar“ und „baz“ enthalten.
Wenn möglich, möchte ich den gesamten Text (nicht nur Name und Beschreibung) aller Manpages durchsuchen.
Ich vermute so etwas wie
man -K foo AND bar AND baz
Antwort1
Ich habe ein Skript implementiert, das genau dies tut.
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
Ich schätze, es war Zeitverschwendung :(
Bearbeiten: Scheint so
man -K expr1 expr2 expr3
hat nicht geklappt?
Edit: Ihr könnt den Skripten nun eure Suchbegriffe übergeben über./script foo bar
Antwort2
Einige Gedanken zum Skripting:
Wird verwendet
manpath
, um den/die Speicherort(e) der Manpages abzurufen. Wenn ich/home/graeme/.cabal/bin
zu meinem hinzufügePATH
, werdenmanpath
(undman
) Manpages in gefunden/home/graeme/.cabal/share/man
.Verwenden Sie man selbst, um die Seiten vor der Suche zu dekomprimieren und zu formatieren. Auf diese Weise durchsuchen Sie nur den man-Text selbst und nicht Kommentare usw. in der Rohdatei. Die Verwendung
man
kann möglicherweise mehrere Formate verarbeiten.Durch das Speichern der formatierten Seiten in einer temporären Datei werden mehrfache Dekomprimierungen vermieden und die Vorgänge sollten erheblich beschleunigt werden.
Hier geht's (mit 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)
Antwort3
Nicht so vollständig wie @polyms Antwort, aber ich wollte so etwas vorschlagen wie
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)
Beachten Sie, dass ich einen -w
(Wortübereinstimmung)-Schalter zu greps
- hinzugefügt habe, was vielleicht nicht das ist, was Sie wollen (möchten Sie Übereinstimmungen wiefoolish und NussBar?)
Antwort4
Dieser Ansatz ist ungetestet, aber ziemlich einfach (blöd einfach), und ich gehe davon aus, dass er funktionieren sollte, auch wenn er ineffizient ist:
#!/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[@]}"