我有一个非常奇怪的情况,我有一个文件系统,其中包含许多大小不同的文件,但在整理文件时似乎已损坏并且不显示任何内容。
我不知道这些文件有多少,它们看起来就像周围的所有其他文件一样。到目前为止,我发现发现它们的最佳方法是运行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 file
true 。file
为了检查文件是否为空(假设它存在),请使用类似
if [ \! -s file ] ; then ... ; fi
或者,您可以使用stat(1)
.这里是 GNU 变体:
$ stat --format=%s foo
1048576
您可以在比较中进一步使用它。
答案2
从你的线索来看:
- 据报告,它们的大小为 0 或非 0
ls -l
- 他们
cat
似乎没有显示任何内容 wc -l
返回 0。
我们可以告诉:
- 它们不包含换行符(
wc -l
计算换行符) - 如果它们包含任何字符,它们在终端中是不可见的
虽然有大量字符在终端中不可见,例如大多数控制字符和一些扩展的 unicode 字符,但对于许多不同的字符腐败显示该行为的文件让我认为这可能是 NUL 字符。
如果对数据块的所有引用都已被删除,则损坏的文件可以被视为全零,其中尺寸inode 中的属性保持不变。这是完全稀疏的文件。
除非 inode 中的块计数字段也损坏,否则您可以使用以下命令检测到这些字段(假设 GNUfind
和awk
):
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