如何在Linux中删除许多0字节文件?

77

我有一个文件夹里面有很多大小为0的文件。当我使用ls命令时,甚至看不到这些文件。我正在使用一个小脚本来删除这些文件,但有时候它甚至不能删除这些文件。以下是脚本:

i=100
while [ $i -le 999 ];do
    rm -f file${i}*;
    let i++;
done

有没有其他更快的方法可以做到这一点?


2
如果文件大小为0字节且“ls”没有显示它们,你怎么知道它们在那里? - JRT
我知道这是因为我能够看到它们几次,这些0字节的文件多次发生,我不知道何时以及如何发生,但有时我可以看到它们,有时就像现在一样看不到它们。然而我知道问题的原因,并且它再次发生了,因此我知道它们在那个目录中。 - small_ticket
1
除了 while [ $i -le 999]let i++,你也可以使用 seq 结合 for i in $(seq ...) - YuppieNetworking
10个回答

149

使用findxargs相结合。

find . -name 'file*' -size 0 -print0 | xargs -0 rm
你可以避免为每个文件启动rm

15
对于 xargs 我给出加一分的评价,它比 -exec 更好用。考虑使用 -print0-0 以提高安全性。 - Martin Wickman
8
-exec选项会为每个参数开始一个新的进程,而xargs则不会。这是在启动进程数量方面的重大改进,并且有助于提高执行时间。请参阅man xargs以获取更多信息。 - Didier Trosset
4
您想使用"-size 0c"选项。 "-size 0"将包含小于512字节的文件。 - tumtumtum
2
@tumtumtum,确实-size 0c更准确(未指定单位默认为块数),但你错误地表示-size 0将包括小于512字节的文件。实际上,只要文件大小达到1字节,它就会占用1个块。 - Didier Trosset
3
这是适用于Ubuntu的命令:find . -type f -name '*' -size 0 -print0 | xargs -r0 rm - seanbreeden
显示剩余4条评论

95

使用GNU的find(请参阅评论),无需使用xargs:

find -name 'file*' -size 0 -delete

3
不错 - 我没意识到find有删除操作。 - GreenMatt
7
仅适用于GNU find命令。 POSIX标准未指定像-delete和-ls这样的操作。 - jim mcnamara
8
请注意,如果您不按名称过滤,则显然不需要“-name 'file *'”部分。 - Skippy le Grand Gourou
8
要创建Skippy评论的可复制粘贴解决方案,只需使用find . -size 0 -delete - Colin D
7
@alper 在使用 find 命令时,第一个参数应该是一个目录,例如 find /home/user/ -name "file* ...". 强烈建议:首先使用 -print 参数而非 -delete 参数,当确认结果符合要求后再删除文件 - coredump
显示剩余3条评论

13

如果您想查找并删除文件夹中的所有0字节文件:

find /path/to/folder -size 0 -delete

7
find . -maxdepth 1 -type f -size 0 -delete

这个命令可以在当前目录下查找大小为0的文件,而不会进入子目录,并将它们删除。

要列出文件但不删除它们:

find . -maxdepth 1 -type f -size 0

6

您可以使用以下命令:

find . -maxdepth 1 -size 0c -exec rm {} \;

如果您希望删除子目录中的0字节文件,请省略前一个命令中的-maxdepth 1并执行。


4

删除当前目录中所有名为file...的文件:

find . -name file* -maxdepth 1 -exec rm {} \;

这将仍然需要很长时间,因为它会为每个文件启动rm


3
我猜你应该使用双引号: -name "file*"否则,模式会被shell扩展。 - Philipp
3
这并不限制rm命令只能删除大小为0的文件。公平地说,OP发布的代码也没有这样做。 - Nathan Fellman
3
你可以使用+代替,这样find命令就能够一次性传递多个文件给rm,而不是每个文件都单独调用一次rm进程。 - Philipp

2

你甚至可以使用选项-delete来删除文件。

来自于find的man文档, -delete 删除文件;如果删除成功则返回true。


1

"...有时甚至无法删除这些文件"让我想到这可能是您经常做的事情。如果是这样,这个Perl脚本将删除当前目录中的任何零字节普通文件。它通过使用系统调用(unlink)避免了rm,速度非常快。

#!/usr/bin/env perl
use warnings;
use strict;

my @files = glob "* .*";
for (@files) {
    next unless -e and -f;
    unlink if -z;
}

嗯,对我来说它是有效的。这一定与您的其他(Java/Selenium相关)问题有关。要么是这样,要么您正在尝试删除的文件不是常规文件。我认为代码没有问题。 - andereld

1

这里有一个例子,自己尝试一下会更容易理解:

bash-2.05b$ touch empty1 empty2 empty3
bash-2.05b$ cat > fileWithData1
Data Here
bash-2.05b$ ls -l
total 0
-rw-rw-r--    1 user group           0 Jul  1 12:51 empty1
-rw-rw-r--    1 user group           0 Jul  1 12:51 empty2
-rw-rw-r--    1 user group           0 Jul  1 12:51 empty3
-rw-rw-r--    1 user group          10 Jul  1 12:51 fileWithData1
bash-2.05b$ find . -size 0 -exec rm {} \;
bash-2.05b$ ls -l
total 0
-rw-rw-r--    1 user group          10 Jul  1 12:51 fileWithData1

如果您查看 man find 命令的手册页面,就会发现这个命令有许多强大的选项。

0

提升一下层次,值得弄清楚这些文件为什么存在。仅仅通过删除它们来处理症状是不够的。如果某个程序正在使用它们来锁定资源,那么你的删除可能会导致损坏。

lsof 是一种可以找出哪些进程控制着空文件的方法之一。


他们在那里的原因在这里:http://stackoverflow.com/questions/3157144/tomcat-creates-0-byte-files 我也在尝试解决这个问题。 - small_ticket

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接