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

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

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

$ cat sample_file.txt
header1,header2,header3,header4
value1,value2,value3,value4

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

$ cat sample_file.txt | head -1 | egrep -o '[[:print:]]' |  tr '\n' '\0'
header1,header2,header3,header4$

我不知道egrep -o '[[:print:]]'这里该做什么。因为即使没有命令,egrep也可以像这样输入

按原样打印标题

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

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

$ cat sample_file.txt | head -1 |  tr '\n' '\0'
header1,header2,header3,header4$

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

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

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

答案1

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

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

$ echo ab:c | egrep -o '[[:alpha:]]'
a
b
c

因此,实际上,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'

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

... | tr -dc '[:print:]'

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

答案2

您可以在中找到解释GNU 的字符类和括号表达式文档:

'[:print:]'
可打印字符:'[:alnum:]'、'[:punct:]' 和空格。


如果您需要整个标头,则不需要任何解析命令,例如egrep等。


man egrep

此外,变体程序egrep、fgrep 和rgrep 分别与grep -E、grep -F 和grep -r 相同。这些变体已被弃用,但提供它们是为了向后兼容。

所以基本上egrep [[:print:]]与 相同grep -E [[:print:]],只有当您需要时才需要扩展正则表达式 (ERE),但该模式[[:print:]]不是其中之一。

相关内容