我有一个包含非文本字符的大日志文件。我使用grep进行搜索,得到了这样的结果:
Binary file (standard input) matches
我可以使用 grep -a 跳过这些包含非文本字符的行。
现在,我如何找出包含非文本字符的所有行?
答案1
GNUgrep
所认为的非文本内容随版本和语言环境的不同而变化。
在第一近似中,您可以尝试:
grep -anPe '^((?!.*$)|.*\0)' < file.log
即查找包含 NUL 字符、0 字节的行(可能是导致该情况的原因)二进制文件如果您的日志文件在打开时被某些没有 O_APPEND 的进程进行写入时被截断,或者是非字符(如果您所在的语言环境具有多字节字符集(如 UTF-8)并且某些行以另一个字符集输出,则可能会出现这种情况)。
假设您的 GNUgrep
是使用 PCRE 支持构建的(对于-P
)。
您可能希望将该输出通过管道传输到类似sed -n l
or hexdump -C
or od -vtc -tx1
(并且可能省略-n
的选项grep
),以尝试识别那些导致二进制信息。
请注意,grep -a
不会跳过这些行,它只是告诉 GNUgrep
不要将其视为的文件二进制特别。如果包含 0 字节或非字符的行与模式匹配,则仍会报告它们。
至少在 Linux 和大多数本机文件系统上,您可以通过以下方式判断文件是否稀疏,即是否具有未分配的部分(孔),这些部分将显示为充满零字节:
perl -le '
seek STDIN,0,4 or die; $hole = tell STDIN;
seek STDIN, $hole, 3 and $data = tell STDIN;
seek STDIN, 0, 2; $end = tell STDIN;
if ($hole != $end) {
print "at least one hole at offset $hole, length ".(($data||$end) - $hole)
}' < file.log
洞只要间隙至少包含一个完整的文件系统块(通常为 4KiB),就会创建一个文件系统。这些漏洞的两侧可能会有更多的 NUL 字节。