检查文件内容是否损坏,文件大小指示大小“零”

检查文件内容是否损坏,文件大小指示大小“零”

我有一个非常奇怪的情况,我有一个文件系统,其中包含许多大小不同的文件,但在整理文件时似乎已损坏并且不显示任何内容。

我不知道这些文件有多少,它们看起来就像周围的所有其他文件一样。到目前为止,我发现发现它们的最佳方法是运行find . -type f | xargs wc -l并查找返回 0 的文件。

然而,其中一些文件有 10 GB,即使它们是空的,也需要一分钟多的时间来检查一个文件。我必须检查大约 5000 万个文件,所以这几乎是不可能的。

我最大的问题是是否有一种较低级别的方法来检查这些文件的内容,这比运行简单的查找要快得多。

答案1

并且在搜索文件时不显示任何内容。

cat文件没有输出并不意味着该文件为空,如以下实验所示:

$ truncate -s 1M foo    
$ ll foo
-rw-r----- 1 user users 1048576 Nov 15 19:28 foo
$ file foo
foo: data
$ cat foo
$ 

cat确实输出了 1MiB 的 NUL 字符,但这些字符恰好在终端中不可见。

您关于空文件的问题有些含糊不清。以上是否foo合格?如果“空”意味着长度为零,那么find可以帮助您:

find dir -type f -empty

列出 . 下的所有零长度文件dir。如果您find不支持-empty,您可以使用-size 0

在 shell 脚本中,您可以使用表达式,如果存在且非空则为-s filetrue 。file为了检查文件是否为空(假设它存在),请使用类似

if [ \! -s file ] ; then ... ; fi

或者,您可以使用stat(1).这里是 GNU 变体:

$ stat --format=%s foo
1048576

您可以在比较中进一步使用它。

答案2

从你的线索来看:

  • 据报告,它们的大小为 0 或非 0ls -l
  • 他们cat似乎没有显示任何内容
  • wc -l返回 0。

我们可以告诉:

  • 它们不包含换行符(wc -l计算换行符)
  • 如果它们包含任何字符,它们在终端中是不可见的

虽然有大量字符在终端中不可见,例如大多数控制字符和一些扩展的 unicode 字符,但对于许多不同的字符腐败显示该行为的文件让我认为这可能是 NUL 字符。

如果对数据块的所有引用都已被删除,则损坏的文件可以被视为全零,其中尺寸inode 中的属性保持不变。这是完全稀疏的文件。

除非 inode 中的块计数字段也损坏,否则您可以使用以下命令检测到这些字段(假设 GNUfindawk):

find . -size +0 -printf '%b%p\0' | awk -v RS='\0' '
  /^0/{print substr($0, 2)}'

即查找大小非零但磁盘使用率为空的文件。

答案3

我最大的问题是是否有一种较低级别的方法来检查这些文件的内容,这比运行简单的查找要快得多。

尝试du

$ truncate -s 4G my4g
$ ls -l my4g
-rw-rw-r-- 1 tange tange 4294967296 Mar  4 15:34 my4g
$ cat my4g
$ du my4g
0       my4g

相关内容