Mat*_*teo 6 unix linux bash grep
我的应用程序日志中包含一个包含奇怪字符的字段。仅当我使用命令时我才能看到这些字符less。
我尝试将代码行的结果复制到文本文件中,我看到的是
CTP_OUT=^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@
Run Code Online (Sandbox Code Playgroud)
我想知道是否有办法找到这些空字符。我尝试过使用grep命令,但没有显示任何内容
我简直不敢相信,我可能会写一个涉及的答案cat!
您观察到的字符是不可打印的字符,通常以Carret 表示法编写。字符的插入符号是一种可视化不可打印字符的方法。正如OP中提到的,^@是 的表示NULL。
如果您的文件包含不可打印的字符,您可以使用以下命令将它们可视化cat -vET:
-E, --show-ends:$在每行末尾 显示
-T, --show-tabs:TAB将字符 显示为^I
-v, --show-nonprinting:使用^和M-表示法,除了LFDand之外TAB来源:
man cat
我已向其中添加了-E和标志,以将所有内容转换为不可打印的内容。-T
由于grep不会以任何形式输出不可打印字符本身,因此您必须通过管道输出才能cat看到它们。以下示例显示包含不可打印字符的所有行
显示所有包含不可打印字符的行:
$ grep -E '[^[:print:]]' --color=never file | cat -vET
Run Code Online (Sandbox Code Playgroud)
此处,ERE[^[:print:]]选择所有不可打印的字符。
显示所有带有以下内容的行NULL:
$ grep -Pa '\x00' --color=never file | cat -vET
Run Code Online (Sandbox Code Playgroud)
请注意,我们需要在这里使用 Perl 正则表达式,因为它们理解十六进制和八进制表示法。
各种控制字符可以用C语言风格编写:
\n匹配换行符、\t制表符、\r回车符、\f换页符等。更一般地,
\nnn,其中nnn是三个八进制数字的字符串,匹配本机代码点为 的字符nnn。如果您没有正好三位数,您很容易遇到麻烦。因此始终使用三个,或者从 Perl 5.14 开始,您可以用来\o{...}指定任意数量的八进制数字。类似地,
\xnn,其中nn是十六进制数字,匹配其本机序数为 的字符nn。同样,不完全使用两位数字会导致灾难,但您可以用来\x{...}指定任意数量的十六进制数字。
一个例子:
$ printf 'foo\012\011\011bar\014\010\012foobar\012\011\000\013\000car\012\011\011\011\012' > test.txt
$ cat test.txt
foo
bar
foobar
car
Run Code Online (Sandbox Code Playgroud)
如果我们现在grep单独使用,我们会得到以下结果:
$ grep -Pa '\x00' --color=never test.txt
car
Run Code Online (Sandbox Code Playgroud)
但通过管道将其传递给cat我们可以可视化控制字符:
$ grep -Pa '\x00' --color=never test.txt | cat -vET
^I^@^K^@car$
Run Code Online (Sandbox Code Playgroud)
原因--color=never:如果你的 grep 被调整为有--color=auto或--color=always它会添加额外的控制字符来解释为终端的颜色。这可能会让您对内容感到困惑。
$ grep -Pa '\x00' --color=always test.txt | cat -vET
^I^[[01;31m^[[K^@^[[m^[[K^K^[[01;31m^[[K^@^[[m^[[Kcar$
Run Code Online (Sandbox Code Playgroud)
sed能。
sed -n '/\x0/ { s/\x0/<NUL>/g; p}' file
Run Code Online (Sandbox Code Playgroud)
-n除非明确要求,否则跳过打印任何输出。
/\x0/仅选择具有空字节的行。封装多个命令,以便始终且仅当检测到线路上为空时才
{...}集体应用它们。用新的可见值替换空字节。你可以随心所欲地做它——我用的东西既相当明显,又不太可能发生。您可能应该先 grep 文件以确保在使用它之前该模式不存在。导致显示已编辑的行(因为它们有空字节)。/\x0/
s/\x0/<NUL>/g;<NUL>
p;
这基本上对空值sed有效grep。