ฉันต้องการค้นหาหน้าคนที่มีคำว่า 'foo', 'bar' และ 'baz' ทั้งหมด
ถ้าเป็นไปได้ฉันต้องการค้นหาข้อความทั้งหมด (ไม่ใช่แค่ชื่อ & คำอธิบาย) ของหน้าเว็บทั้งหมด
ฉันคาดเดาบางอย่างเช่น
man -K foo AND bar AND baz
ฉันต้องการค้นหาหน้าคนที่มีคำว่า 'foo', 'bar' และ 'baz' ทั้งหมด
ถ้าเป็นไปได้ฉันต้องการค้นหาข้อความทั้งหมด (ไม่ใช่แค่ชื่อ & คำอธิบาย) ของหน้าเว็บทั้งหมด
ฉันคาดเดาบางอย่างเช่น
man -K foo AND bar AND baz
คำตอบ:
ฉันใช้สคริปต์ที่ทำสิ่งนี้
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
or
ฉันคิดว่าเป็นand
เพราะฉันไม่ได้ทดสอบอย่างถูกต้อง
ความคิดเล็ก ๆ น้อย ๆ เกี่ยวกับการเขียนสคริปต์นี้:
ใช้manpath
เพื่อรับตำแหน่งของ man pages ถ้าฉันจะเพิ่ม/home/graeme/.cabal/bin
ของฉันPATH
, manpath
(และman
) /home/graeme/.cabal/share/man
จะพบหน้าคนใน
ใช้ man ตัวเองเพื่อขยายและจัดรูปแบบหน้าก่อนค้นหาด้วยวิธีนี้คุณเพียงแค่ค้นหาข้อความตัวเองและไม่แสดงความคิดเห็นใด ๆ ในไฟล์ raw การใช้man
อาจจะเกี่ยวข้องกับหลายรูปแบบ
การบันทึกเพจที่จัดรูปแบบใน tempfile จะหลีกเลี่ยงการแตกไฟล์หลายไฟล์และควรเร่งให้มีความเร็วมากขึ้น
ไปที่นี่ (พร้อมbash
และ GNU ค้นหา):
#!/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)
ไม่สมบูรณ์เหมือนคำตอบของ @ 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หรือไม่)
วิธีนี้ไม่ได้ทดสอบ แต่ค่อนข้างง่าย (โง่ง่าย) และฉันคาดหวังว่ามันจะทำงานแม้ว่าไม่มีประสิทธิภาพ:
#!/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[@]}"