尝试查找仅包含 NUL 的文件,但获取其他一些文件

pbi*_*ies 8 command-line text-processing

我试图查找/列出的文件是:

  • 任意大小(接受 0 字节)
  • 仅由 ASCII NUL 字符 (0x00) 组成
  • 如果有除 0x00 以外的任何字符,则不应列出该文件。

我现在的命令是:

grep -RLP '[^\x00]' .
Run Code Online (Sandbox Code Playgroud)

哪个有效,但它也会找到仅包含两个字节的文件:0xFF、0xFE。不知道为什么。

有没有更好的命令来查找此类文件?

fil*_*den 9

简而言之,这里发生的事情grep是试图将您的文件解释为 Unicode 数据。序列 0xFF, 0xFE 是UTF-16字节顺序标记

(在我的测试中,即使涉及两个 0xFF 或两个 0xFE 等的其他序列仍然不匹配'[^\x00]'正则表达式,因为即使在尝试执行 UTF-8 时,这些也会被视为非字符。)

使用不将 Unicode 用于字符类型的语言环境应该可以解决此问题,您可以通过设置LC_CTYPE 环境变量来实现。使用C语言环境强制 ASCII 编码(因此没有启用 Unicode):

LC_CTYPE=C grep -RLP '[^\x00]' .
Run Code Online (Sandbox Code Playgroud)

更新:正如@steeldriver 所指出的,grep 仍然逐行运行,因此包含 NUL 字节和换行符的文件仍将匹配。

@DavidFoerster 使用 grep 的解决方案-z很好地解决了这个问题,使用 NUL 字节作为分隔符可以解决问题。

或者,我想出了一个简短的 Python 3 脚本 ( allzeroes.py) 来检查文件的内容是否全为零:

#!/usr/bin/python3
import sys
assert len(sys.argv) == 2
with open(sys.argv[1], 'rb') as f:
    for block in iter(lambda: f.read(4096), b''):
        if any(block):
            sys.exit(1)
Run Code Online (Sandbox Code Playgroud)

您可以在 a 中使用它find来递归定位所有匹配项:

$ find . -type f -exec allzeroes.py {} \; -print
Run Code Online (Sandbox Code Playgroud)

我希望这有帮助。

  • +1虽然因为`grep`是基于行的,这也将输出完全由换行符组成的文件-您可以通过使用`-z`指定以空字符结尾的模式来解决这个问题(尽管这会吞掉任何常规文本文件完全进入内存)。另外我认为这里不需要`-P`吗? (3认同)