15

我试图想出一种在手册页中找到特定标志的方法。通常,我输入“/”来搜索某些内容,然后输入“-Werror”之类的内容来查找特定标志。问题是虽然有一些手册页(gcc 是现在激励我的一个)在其文本中引用了很多标志,所以出现了很多。

这没什么大不了的,但也许可以做得更好。我想寻找类似 '-O\n' 的东西,但它没有用(可能是因为 man 程序不使用 C 转义?)然后我尝试了类似man gcc | grep $'-O\n'的东西,因为我记得一个单一的 -以美元符号开头的带引号的字符串具有 bash 解释常见的 C 转义...它不起作用,grep 回显了整个手册页。

这就是把我带到这里的原因:为什么?或者更确切地说,可以这样做吗?

4

8 回答 8

9

rici 的有用答案很好地解释了原始方法的问题。

不过,还有一点值得一提:

man的输出包含格式控制字符,这会干扰文本搜索

如果您在 search之前使用管道传输到col -b,这些控制字符将被删除 - 请注意搜索结果也将是纯文本的副作用。

但是,grep这不是这项工作的正确工具;我建议使用awk如下方式获取描述-O

man gcc | col -b | awk -v RS= '/^\s+-O\n/'
  • RS=(一个空的输入记录分隔符)是一个 awk 习惯用法,它将输入分成非空行的块,因此在此类块的开头匹配选项可确保返回包含选项描述的所有行

如果你有一个 POSIX-features-onlyawk例如 BSD/OSX awk,使用这个版本:

man gcc | col -b | awk -v RS= '/^[[:blank:]]+-O\n/'

显然,这样的命令键入起来有些麻烦,所以在下面找到泛型bash函数,它manopt从其man页面返回指定命令的指定选项的描述。(可能存在误报和误报,但总体而言效果很好。)

例子:

manopt gcc O          # search `man gcc` for description of `-O`
manopt grep regexp    # search `man grep` for description of `--regexp`
manopt find '-exec.*' # search `man find` for all actions _starting with_ '-exec'

bash功能manopt()- 放置在 中~/.bashrc,例如:

# SYNOPSIS
#   manopt command opt
#
# DESCRIPTION
#   Returns the portion of COMMAND's man page describing option OPT.
#   Note: Result is plain text - formatting is lost.
#
#   OPT may be a short option (e.g., -F) or long option (e.g., --fixed-strings);
#   specifying the preceding '-' or '--' is OPTIONAL - UNLESS with long option
#   names preceded only by *1* '-', such as the actions for the `find` command.
#
#   Matching is exact by default; to turn on prefix matching for long options,
#   quote the prefix and append '.*', e.g.: `manopt find '-exec.*'` finds
#   both '-exec' and 'execdir'.
#
# EXAMPLES
#   manopt ls l           # same as: manopt ls -l
#   manopt sort reverse   # same as: manopt sort --reverse
#   manopt find -print    # MUST prefix with '-' here.
#   manopt find '-exec.*' # find options *starting* with '-exec'
manopt() {
  local cmd=$1 opt=$2
  [[ $opt == -* ]] || { (( ${#opt} == 1 )) && opt="-$opt" || opt="--$opt"; }
  man "$cmd" | col -b | awk -v opt="$opt" -v RS= '$0 ~ "(^|,)[[:blank:]]+" opt "([[:punct:][:space:]]|$)"'
}

fish实施manopt()

Ivan Aracki提供。

function manopt 
  set -l cmd $argv[1]
  set -l opt $argv[2] 
  if not echo $opt | grep '^-' >/dev/null
    if [ (string length $opt) = 1 ] 
      set opt "-$opt"
    else
      set opt "--$opt"
    end
  end
  man "$cmd" | col -b | awk -v opt="$opt" -v RS= '$0 ~ "(^|,)[[:blank:]]+" opt "([[:punct:][:space:]]|$)"'
end
于 2014-07-26T04:21:52.030 回答
5

我怀疑您实际上并没有使用grep $'-O\n',而是使用了一些被grep.

从 grep 的角度来看,您只是在传递一个参数,并且该参数以 a 开头,-因此它将被解释为一个选项。您需要做一些事情,比如grep -- -O$显式标记选项列表的结尾,或者grep -e -O$显式地将模式标记为模式。无论如何,您不能在模式中包含换行符,因为 grep 模式实际上是由换行符分隔的模式列表,因此参数$'foo\n'实际上是两个模式,foo空字符串和空字符串将匹配每一行。

也许您搜索了标志-e,因为它将模式作为参数,并给它一个换行符作为参数将导致 grep 查找整个文件中的每一行。

对于大多数 GNU 程序,例如 gcc,您可能会发现info界面更易于导航,因为它包括参考链接、目录,甚至索引。该info gcc文档包含一个选项索引,非常有用。在某些 linux 发行版中,有些令人惊讶的是,因为它们自称为 GNU/linux 发行版,info尽管man文件与基本软件一起分发,但仍需要单独安装软件包。info例如,包含 gcc文件的 debian/ubuntu 软件包称为gcc-doc。(-doc包名后缀的使用很常见。)

在这种情况下,gcc您可以使用以下命令快速找到一个选项:

info gcc "option index" O

或者

info gcc --index-search=funroll-loops

对于选项较少的程序,通常使用 info 的选项就足够了-O

info -O gawk
于 2013-10-05T15:05:38.673 回答
1

问题是“man”使用寻呼机,通常是“less”,其手册页指出:

/pattern
    Search  forward  in  the file for the N-th line containing the pattern.
    N defaults to 1.  The pattern is a regular expression, as recognized by the
    regular expression library supplied by your system.  The search starts at the
    first line displayed (but see the -a and -j options, which change this).

因此,可以尝试在手册页中查找“-O$”,以找到一个单独存在于它自己行中的标志。虽然,在同一行中,一个标志后面跟着文本是很常见的,所以这不能保证有效。

grep 和 $'-O\n' 的问题仍然是个谜。

于 2013-10-05T14:37:16.850 回答
1

我使用以下内容:

man some_command | col -b | grep -A5 -- 'your_request'

例子:

  • man man | col -b | grep -A5 -- '-K'

  • man grep | col -b | grep -A5 -- '-e patt'

您可以为其创建别名。

于 2019-01-22T14:28:06.480 回答
1

manly Python 实用程序非常方便快速解释给定命令中使用的所有选项。

请注意,它仅输出选项描述的第一段。

pip install manly
$ manly blkid /dev/sda -o value -p

blkid - locate/print block device attributes
============================================

      -o, --output format
              Use  the  specified output format.  Note that the order of vari‐
              ables and devices is not fixed.  See also option -s.  The format
              parameter may be:

      -p, --probe
              Switch to  low-level  superblock  probing  mode  (bypassing  the
              cache).
于 2020-01-09T11:35:49.913 回答
1

在大多数 bash 内置命令和许多其他命令中使用双破折号 (--) 来表示命令选项的结束

https://unix.stackexchange.com/a/11382/204245

如果没有双破折号,grep则尝试使用您正在寻找的任何标志:

$ man curl | grep -c # Looks for this c flag, but can't find one so throws the error below.
usage: grep [-abcDEFGHhIiJLlmnOoqRSsUVvwxZ] [-A num] [-B num] [-C[num]]
    [-e pattern] [-f file] [--binary-files=value] [--color=when]
    [--context[=num]] [--directories=action] [--label] [--line-buffered]
    [--null] [pattern] [file ...]

如果您使用双破折号来表示对 的输入的结束grep,它的效果会好一些,但您仍然会得到每次匹配的结果:

$ man curl | grep -- -c
       --cacert <file>
              certs file named 'curl-ca-bundle.crt', either in the same direc-
       --capath <dir>
              curl to make SSL-connections much more  efficiently  than  using
              --cacert if the --cacert file contains many CA certificates.
       --cert-status
       --cert-type <type>
       -E, --cert <certificate[:password]>
       --ciphers <list of ciphers>
# ...many more matches......

因此,只需将标志括在引号中并在其前添加一个空格以仅匹配-c标志:

$ man curl | grep -- " -c"
       -c, --cookie-jar <filename>

这让我发疯了很多年。希望这可以帮助。

于 2020-05-08T18:35:45.400 回答
0
man gcc | grep "\-" 

这工作得很好,因为它显示所有标志,通常不多。

编辑:我注意到我没有完全回答你的问题,但我希望我的建议可以被视为一个不错的选择。

于 2014-07-26T00:59:37.660 回答
0

man基于环境变量(EDITOR如果我没记错的话)。您可以将其从more(默认值)更改为,例如,emacs然后在使用man会话emacs时在您的系统上打开,您可以在其中随意搜索和浏览。

于 2018-07-03T14:42:08.147 回答