bash 中的egrep [[:print:]] 命令有什么用?

Shr*_*hri 6 linux shell grep bash

我正在开发一个 shell 脚本的增强功能,它可以读取文件并处理它。基本上,输入文件包含一个标题记录,后面跟着一些详细记录。我只想从文件中获取头记录。

$ cat sample_file.txt
header1,header2,header3,header4
value1,value2,value3,value4
Run Code Online (Sandbox Code Playgroud)

现有脚本使用以下命令从文件中获取标头:

$ cat sample_file.txt | head -1 | egrep -o '[[:print:]]' |  tr '\n' '\0'
header1,header2,header3,header4$
Run Code Online (Sandbox Code Playgroud)

我不知道egrep -o '[[:print:]]'在这里做什么。因为即使没有这个egrep命令也可以这样写

按原样打印标题

$ cat sample_file.txt | head -1
header1,header2,header3,header4

Run Code Online (Sandbox Code Playgroud)

或者打印标题而不在末尾换行

$ cat sample_file.txt | head -1 |  tr '\n' '\0'
header1,header2,header3,header4$
Run Code Online (Sandbox Code Playgroud)

的手册页egrep讲述了以下内容,但不清楚何时[[:print:]]应该使用。

最后,在括号表达式中预定义了某些命名的字符类,如下所示。它们的名称是不言自明的,它们是 [:alnum:]、[:alpha:]、[:cntrl:]、[:digit:]、[:graph:]、[:lower:]、[:print:] 、[:punct:]、[:space:]、[:upper:] 和 [:xdigit:]。例如,[[:alnum:]] 表示 [0-9A-Za-z],但后一种形式取决于 C 语言环境和 ASCII 字符编码,而前者独立于语言环境和字符集。(请注意,这些类名称中的方括号是符号名称的一部分,除了界定方括号列表的方括号之外还必须包含方括号。)大多数元字符在列表中会失去其特殊含义。要包含文字 ],请将其放在列表的第一位。类似地,要包含文字 ^,请将其放置在除开头之外的任何位置。最后,要包含文字 - 将其放在最后。

您能帮我理解egrep '[[:print:]]'选项的用法以及我们在哪里使用它吗?

ilk*_*chu 4

括号表达式类似于[abc],它匹配其中的任何一个字符。例如[abc]会匹配aor b,但不匹配dor :。可以在括号表达式中使用字符类,以将整个类添加到括号表达式匹配的集合中。[[:print:]]将匹配单个可打印字符,保留控制字符、换行符和制表符。egrep,或者最好是grep -E,将打印与给定模式匹配的任何行,并且-o仅打印匹配的部分,每行一个

例如[:alpha:],使用 时,冒号被省略:

$ echo ab:c | egrep -o '[[:alpha:]]'
a
b
c
Run Code Online (Sandbox Code Playgroud)

因此,实际上,egrep -o '[[:print:]]'将打印输入中的每个可打印字符,每行一个。然后tr '\n' '\0'将换行符更改为 NUL 字节,这样您就可以获得所有中间带有 NUL 的可打印字符。我不确定这是否有意义,因为 NUL 并不比控制字符更好处理。less如果您在例如或中打开结果数据vim,您将看到 NUL 打印为^@,可能是彩色的。

同样,cat sample_file.txt | head -1 | tr '\n' '\0'不会删除换行符,而是将其替换为 NUL。


我不确定这里的目标是什么,但要删除任何换行符和制表符,您可以使用tr -d

... | tr -d '\n\t'
Run Code Online (Sandbox Code Playgroud)

并删除所有不可打印的字符-d-c补充(反转)匹配的字符集:

... | tr -dc '[:print:]'
Run Code Online (Sandbox Code Playgroud)

(请注意,它tr并不像正则表达式中那样采用外部括号。实际上, to 的参数tr就像正则表达式括号表达式的内部。)