Grep与手册页的某些部分不匹配

时间:2019-06-23 09:32:15

标签: bash macos grep man

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 Beta版
bash:GNU bash,版本5.0.7(1)-发行版(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

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

2 个答案:

答案 0 :(得分: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内容的文本。看看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

答案 1 :(得分:1)

macOS man不支持--ascii标志,因此我使用col -bx从man中去除了烦人的格式,以便传递给其他命令。

man sed | col -bx | grep SYNOPSIS

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

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