找出大日志文件中所有带有二进制非文本字符的行号

找出大日志文件中所有带有二进制非文本字符的行号

我有一个包含非文本字符的大日志文件。我使用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 lor hexdump -Cor 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 字节。

相关内容