【问题标题】:Grep not matching certain parts of man pageGrep 与手册页的某些部分不匹配
【发布时间】:2019-11-05 10:28:44
【问题描述】:

Grep 似乎与 man 输出中的某些字符串不匹配。这似乎是随机的,因为我无法确定字符串是否匹配的任何押韵或原因。

man sed | head -7:

SED(1)                    BSD General Commands Manual                   SED(1)

NAME
     sed -- stream editor

SYNOPSIS
$ man sed | head -7 | grep sed # no match

$ man sed | head -7 | grep stream # match on "stream"
     sed -- stream editor

$ man sed | head -7 | grep '\-\-' # match on "--"
     sed -- stream editor

$ man sed | head -7 | grep NAME # no match

$ man sed | head -7 | grep SYNOPSIS # no match

在将输出重定向到文件并对其进行 grepping 时也会发生这种情况

$ man sed | head -7 > /tmp/sed.man

$ cat /tmp/sed.man | grep sed # no match

$ cat /tmp/sed.man | grep stream # match on "stream"
     sed -- stream editor

$ grep sed /tmp/sed.man # no match

$ grep stream /tmp/sed.man # match on "stream"
     sed -- stream editor

grep: grep (BSD grep) 2.5.1-FreeBSD
男人:版本 1.6c
macOS:10.14.6 测试版
bash:GNU bash,版本 5.0.7(1)-release (x86_64-apple-darwin18.5.0)

$ man sed | head -7 | hexdump -C
00000000  0a 53 45 44 28 31 29 20  20 20 20 20 20 20 20 20  |.SED(1)         |
00000010  20 20 20 20 20 20 20 20  20 20 20 42 53 44 20 47  |           BSD G|
00000020  65 6e 65 72 61 6c 20 43  6f 6d 6d 61 6e 64 73 20  |eneral Commands |
00000030  4d 61 6e 75 61 6c 20 20  20 20 20 20 20 20 20 20  |Manual          |
00000040  20 20 20 20 20 20 20 20  20 53 45 44 28 31 29 0a  |         SED(1).|
00000050  0a 4e 08 4e 41 08 41 4d  08 4d 45 08 45 0a 20 20  |.N.NA.AM.ME.E.  |
00000060  20 20 20 73 08 73 65 08  65 64 08 64 20 2d 2d 20  |   s.se.ed.d -- |
00000070  73 74 72 65 61 6d 20 65  64 69 74 6f 72 0a 0a 53  |stream editor..S|
00000080  08 53 59 08 59 4e 08 4e  4f 08 4f 50 08 50 53 08  |.SY.YN.NO.OP.PS.|
00000090  53 49 08 49 53 08 53 0a                           |SI.IS.S.|
00000098

谷歌搜索很难解决这个问题,因为“man”或“grep”的任何组合都没有提到我的字符串(没有特殊字符)不匹配的问题。

【问题讨论】:

  • 对不起,macOS,我会添加那个
  • 一切都为我工作,Ubuntu Linux
  • 你试过man --ascii sed | head -7 | grep sed
  • 我的猜测是 man 检测到输出是否为文件并调整内容
  • 如果hexdump 可用,请将man sed | head -7 | hexdump -C 的输出添加到您的问题中。

标签: bash macos grep manpage


【解决方案1】:

手册页使用 roff 格式 (https://man.openbsd.org/roff)。执行以下操作:

man sed > sed.man
vi sed.man

如你所见:

SED(1)                    BSD General Commands Manual                   SED(1)

N^HNA^HAM^HME^HE
     s^Hse^Hed^Hd -- stream editor

将手册页转换为不带 ^H-stuff 的文本。看看http://www.schweikhardt.net/man_page_howto.html#q10

创建一个名为strip-headers 的perl-Skript,内容如下:

#!/usr/bin/perl -wn
#  make it slurp the whole file at once:
undef $/;
#  delete first header:
s/^\n*.*\n+//;
#  delete last footer:
s/\n+.*\n+$/\n/g;
#  delete page breaks:
s/\n\n+[^ \t].*\n\n+(\S+).*\1\n\n+/\n/g;
#  collapse two or more blank lines into a single one:
s/\n{3,}/\n\n/g;
#  see what is left...
print;

更改 perl 脚本 chmod 750 strip-headers 的权限并运行它:

man sed | ./strip-headers | col -bx > sed.man

man sed | ./strip-headers | col -bx | head -7 | grep sed

【讨论】:

  • 是的,我明白了。我没有意识到cat sed.manvi sed.man 会显示不同的输出。你知道这种格式被称为什么或如何在没有--ascii 的情况下修复它?
  • 它被称为 roff 格式。也许你可以用 groff 转换它。
【解决方案2】:

macOS man 不支持 --ascii 标志,所以我使用 col -bx 去除了 man 中烦人的格式,以便管道到其他命令中。

man sed | col -bx | grep SYNOPSIS

col -b:不输出任何退格,只打印写入每个列位置的最后一个字符。
col -x:输出多个空格而不是制表符。

注意事项:
我读过那个 man 是为了检测你是在管道到另一个命令还是到一个文件等,但这不是我的经验。至少对于 man 1.6c,macOS 的默认值。
使用col的解决方案:https://unix.stackexchange.com/a/15866
谢谢@Cyrus - 我不知道hexdump
谢谢@Oliver Gaida - 我不知道 cat 和 vi 会以不同的方式显示

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-09-15
    • 2012-01-22
    • 2018-10-17
    • 2016-05-02
    • 2010-11-11
    • 1970-01-01
    • 1970-01-01
    • 2011-12-01
    相关资源
    最近更新 更多