如何快速确定哪些文件只包含 NULL 以便可以安全删除它们(Windows)?

如何快速确定哪些文件只包含 NULL 以便可以安全删除它们(Windows)?

一位朋友有数千个文件,其中可能只包含 NULL(ASCII 0)。

(如果有兴趣,请参阅超级用户问答了解原因)。

这些文件的大小从 650 字节到 ~200MB 不等(大多数为 4-8MB)。

在 Windows 中,有什么方法可以快速确定哪些文件只包含 NULL,然后可以删除它们?

如果可能的话,最好使用内置的 Windows(7)工具。

我在想类似的事情:

findstr /m /s /r ^(\x00)+$ *.*

可以找到仅由 NULL 组成的文件,但在测试中,它不会返回任何结果。


更新 1:

我对此进行了更多实验,发现:

findstr /m /s /r [^\x00] *

可能正在努力寻找逆文件(不是仅包含NULL),这也可以用来达到目标​​。

但奇怪的是:

findstr /m /s /r [^\000] *

产生不同的结果。

因为十六进制 0(\x00在正则表达式中)= 八进制 0(\000在正则表达式中),所以我希望这两个命令得到相同的结果。

这让我怀疑这些命令中至少有一个的结果是否不正确。


更新 2:

嗯,看起来是这样的:

findstr /m /s /r [^\x00] *

可能会正常工作,并且事实是:

findstr /m /s /r [^\000] *

产生不同的结果很可能是微软的另一个错误(如果它们应该产生不同的结果,请纠正我,解释为什么这两个命令会产生不同的结果)

我使用优秀的跨平台证实了这一点瑞士锉刀第三方工具。

初步测试揭示了 SFK 命令的结果:

sfk xfindbin . "/[byte not \x00]/" -names

与 匹配findstr /m /s /r [^\x00] *,但不匹配findstr /m /s /r [^\000] *。这让我相信我可能又发现了微软findstr命令中的另一个错误(参见SS64了解该 Microsoft 工具中其他错误的摘要)。


更新 3:

进一步的测试揭示了SFK命令的结果:

sfk xfindbin . "/[byte not \x00]/" -names

findstr /m /s /r [^\x00] *正确找到和未找到的一些文件findstr /m /s /r [^\000] *

答案1

我能够使用这个 power shell 脚本来找到没有内容或只有空值的文件:

$files = Get-ChildItem -Path c:\somepath\tostartfrom -Recurse -File
foreach ($f in $files){
    $content = Get-Content -Path $f.FullName -TotalCount 10
    if ($content -match '[\\x01-\\xFF]+') { 
        #do nothing as file has a valid character in it
    }
    else {Write-Output $f.FullName}
}
Write-Host -NoNewLine 'Press any key to continue...';
$null = $Host.UI.RawUI.ReadKey('NoEcho,IncludeKeyDown');

您可以使用

c:\test\ps\findnullfiles.ps1 | Out-File -FilePath c:\test\ps\results.txt

将信息发送到文本文件以供日后使用。在 else 子句中添加额外的测试,您可以根据需要跳过没有内容的文件。

答案2

解释情况:

在中FINDSTR/S是递归的,/R是正则表达式:使用它将给出匹配的行,而不是文件名。

因此我们必须使用/M:来打印文件名,而不是匹配的行。

现在,给定的正则表达式是^(\x00)+$括号“ (”和“ )”不是分组(像在 Perl 中)而是单个字符,因此在每个 NULL 文件中都没有任何匹配项。

另一个正则表达式是,[^\x00]不是^行首 ,而是字符类的否定。
它应该是^[\x00]行首 ,假设支持搜索 NULL 字符。
同样,[^\000]应该是^[\000],同样假设支持 NULL 字符。

不幸的是,FINDSTR寻找空字符时不会给出正确的结果:

https://ss64.com/nt/findstr.html
“FINDSTR 无法搜索 Unicode 文件中常见的空字节。”

还有其他 BUGS。

解决方案1:
使用/X(打印完全匹配的行)和正则表达式[\x00]+[\000]+,将检查整行,假设FINDSTR可以查看空字符。

解决方案2:
安装并使用PERL,它将发挥神奇的作用。

相关内容