我想man
更有效地使用。我决定尝试一下--regex
。然而:
~$ man --regex -K '.*textdomain.*perl.*'
--Man-- next: Locale::Messages(3pm) [ view (return) | skip (Ctrl-D) | quit (Ctrl-C) ]
^C
~$ man --regex -K '.*perl.*textdomain.*'
No manual entry for .*perl.*textdomain.*
我提取的源代码(首先查找哪个人打开)会产生空的 grep 结果,但会分别查找单词(textdomain、perl):
~/Documents$ grep '.*textdomain.*perl.*' Locale\:\:libintlFAQ.3pm
~/Documents$ grep '.*perl.*textdomain.*' Locale\:\:libintlFAQ.3pm
perl
在该文件中,(例如第 74 行)位于textdomain
(例如第 120 行)之前。为什么man --regex -K '.*perl.*textdomain.*'
单词顺序颠倒了就找不到了?grep
显示两个序列都不在一行上。实际上如何man --regex -K
运作?是否应该.*
寻找新线路?我想最后一个答案是“这取决于系统”(基于https://stackoverflow.com/questions/11924480/search-in-man-page-for-words-at-the-beginning-of-line)。
答案1
在man
实施中从man-db
正如大多数 GNU/Linux 发行版中所发现的那样,搜索是基于行的和默认不区分大小写(除非您传递-I
/--match-case
选项)。
$ man -Iw --regex -K '.*textdomain.*perl.*'
No manual entry for .*textdomain.*perl.*
$ man -w --regex -K '.*textdomain.*perl.*'
/usr/share/man/man3/Locale::libintlFAQ.3pm.gz
/usr/share/man/man3/Locale::TextDomain.3pm.gz
/usr/share/man/man3/Locale::libintlFAQ.3pm.gz
/usr/share/man/man3/Locale::TextDomain.3pm.gz
$ zgrep '.*textdomain.*perl.*' /usr/share/man/man3/Locale::libintlFAQ.3pm.gz
$ zgrep -i '.*textdomain.*perl.*' /usr/share/man/man3/Locale::libintlFAQ.3pm.gz
Locale::TextDomain::FAQ \- Frequently asked questions for libintl\-perl
要搜索同时包含perl
和textdomain
且区分大小写的手册页,您可以执行以下操作(在 GNU 系统上):
xargs -rd '\n' -a <(
man -IKw perl | sort -u | xargs -rd '\n' zgrep -l textdomain --
) man -l --
perl
进行搜索man -IKw
,返回包含它的手册页的路径,textdomain
在这些文件中进行搜索zgrep
,并将结果路径列表提供给man -l
。
脚本man-pages-with-all-words
可以写成:
#! /bin/zsh -
die() {
print -rC1 -u2 - "$@"
exit 1
}
(( $# )) || die "Usage: $ZSH_SCRIPT <word> [<word>...]"
typeset -U pages
pages=(
${(f)"$(man -IKw -- "$1")"}
)
shift
while (( $#pages && $# )); do
pages=(
${(f)"$(zgrep -lF -- "$1" $pages)"}
)
shift
done
if (( $#pages )); then
man -l -- $pages
else
die "No matching man page found."
fi
sh
或者与 POSIX语法相同:
#! /bin/sh -
die() {
[ "$#" -eq 0 ] || printf '%s\n' "$@"
exit 1
}
[ "$#" -gt 0 ] || die "Usage: $0 <word> [<word>...]"
# tune sh split+glob: split on (sequences of) newline + no glob
IFS='
'; set -o noglob
pages=$(man -IKw -- "$1" | LC_ALL=C sort -u)
shift
while [ "$#" -gt 0 ] && [ -n "$pages" ]; do
pages=$(
zgrep -lF -- "$1" $pages
)
shift
done
if [ -n "$pages" ]; then
man -l -- $pages
else
die "No matching man page found."
fi