文件太多,执行
rm -rf
会返回错误,而我们需要做的事情是这样的:find /path/to/folder -name "filenamestart*" -type f -exec rm -f {} \;
此方法有效,但速度很慢,并且经常会因内存不足而失败。
是否有更好的方法?理想情况下,我希望删除整个目录而不关心其中的内容。
#1 楼
使用rsync令人惊讶,快速且简单。mkdir empty_dir
rsync -a --delete empty_dir/ yourdirectory/
@sarath的答案提到了另一个快速选择:Perl!它的基准测试速度比
rsync -a --delete
快。 unix-fast-remove-directory-for-cleaning-up-daily-builds http://www.slashroot.in/which-is-the-fastest-method-to-delete-files-in-linux
评论
谢谢,非常有用。我一直在使用rsync,我不知道您可以使用rsync这样删除。比rm -rf快得多
–约翰·鲍威尔(John Powell)
2014年8月21日在19:41
rsync可以比普通rm更快,因为它保证删除顺序正确,因此需要较少的btress重新计算。看到这个答案serverfault.com/a/328305/105902
– Marki555
15年6月29日在12:45
任何人都可以修改perl表达式以递归删除directory_to_be_deleted中的所有目录和文件吗?
– Abhinav
2015年10月6日15:43
注意:在rsync上添加-P选项可获得更多显示,此外,请注意语法,斜杠是必需的。最后,您可以首次使用-n选项来首次启动rsync命令以启动试运行。
–Drasill
15-10-23在15:39
****极端警告****是Gobinath(在上面的评论中)在上面的github.com地址生成的脚本。根据我的实验,这可能会导致数据意外丢失……尤其是我认为,这似乎会导致符号链接被浏览并且其内容被删除。我建议大家在认真使用它之前先进行详细的试验!
–麦克·啮齿动物
20年1月10日在19:03
#2 楼
Twitter上有人建议使用-delete
而不是-exec rm -f{} \;
这样可以提高命令的效率,尽管如此,它仍然使用递归来遍历所有内容。
评论
这是非标准的。 GNU查找具有-delete,也许其他查找。
– Enzotib
2012年4月26日上午9:11
出于安全和效率考虑,在可用时,始终应优先于-exec rm使用-delete。
– jw013
2012年4月26日上午11:37
GNU是事实上的标准。
–罗恩·约翰(RonJohn)
18年3月3日在17:38
只是警告-在gnu find中添加-delete会隐式启用-depth,这使您回到扫描期间内存不足的问题。
–戴夫
20年12月11日,0:05
#3 楼
诸如此类的事情:find /path/to/folder -name "filenamestart*" -type f -print0 | xargs -0rn 20 rm -f
您可以通过更改参数
-n
的参数来限制一次删除的文件数。还包括带有空白的文件名。评论
您可能不需要-n 20位,因为xargs应该将其自身限制为可接受的参数列表大小。
–没用
2012年4月26日13:41
是的,你是对的。这是man xargs的注释:(...)每个命令行(...)的最大字符数。允许的最大值取决于系统,并且被计算为exec的参数长度限制。因此,-n选项适用于xargs无法确定CLI缓冲区大小或执行的命令具有某些限制的情况。
–digital_infinity
2012年4月26日13:50
#4 楼
一个巧妙的技巧:rsync -a --delete empty/ your_folder/
它占用大量的CPU资源,但速度确实非常快。参见https://web.archive.org/web/20130929001850/http://linuxnote.net/jianingy/zh/linux/a-fast-way-to-remove-huge-number-of-files.html
评论
速度不是很快,因为它无法有效地读取目录内容。请参阅此答案以获取10倍更快的解决方案和说明serverfault.com/a/328305/105902
– Marki555
15年6月29日在12:46
@ Marki555:在问题的编辑中,rsync -a --delete报告为60秒,而lsdent报告为43秒。比率10x对于时间ls -1 | wc -l vs time ./dentls bigfolder> out.txt(由于> file vs wc -l,这是部分公平的比较)。
–
16年1月21日在9:30
那里的问题是,那里的命令中没有一个实际上执行删除所需的遍历操作。他们给的密码?不能按Marki555所述工作。
–斯瓦尔塔夫
18-09-10的16:05
#5 楼
扩展其中一条评论,我认为您没有按照自己的想法做。首先,我创建了大量的文件来模拟您的情况:
$ mkdir foo
$ cd foo/
$ for X in $(seq 1 1000);do touch {1..1000}_$X; done
然后我尝试了我预期会失败的事情,听起来像是您在做这个问题: >但这确实有效:
$ rm -r foo/*
bash: /bin/rm: Argument list too long
评论
这是唯一有效的解决方案:多次运行rm -Rf bigdirectory。我有一个包含成千上万个子目录和文件的目录。我什至无法在该目录中运行ls或find或rsync,因为它内存不足。 rm -Rf命令多次退出(内存不足),仅删除了数十亿文件的一部分。但是经过多次重试,它终于完成了工作。如果出现内存不足的问题,这似乎是唯一的解决方案。
–erik
2014年4月9日在13:01
#6 楼
与-delete
相比,我有机会测试-exec rm \{\} \;
,对我来说-delete
是此问题的答案。 br /> “如何在linux中删除大量文件”一文表明它的速度快了大约三倍,但在我的测试中,区别要大得多。
评论
使用find -exec对每个文件分别执行rm命令,这就是为什么它这么慢的原因。
– Marki555
15年6月26日在21:43
使用GNU find,这是-exec rm {} \ +派上用场的地方(特别是\ +代替\;),因为它像内置xargs一样工作,而没有最少的管道和派生开销。不过,它仍然比其他选项慢。
– dannysauer
19/12/2在23:12
@dannysauer execplus由AT&T的David Korn于1988年发明,GNU find是最后一个添加支持的实现-超过25年。顺便说一句:标准execplus和非标准-delete之间的速度差异很小。
–schily
20-2-22在10:09
@schily,这很有趣,我非常喜欢Korn的作品。但是,我们正在评论的答案表明测试是在Linux上进行的。指定了“ GNU查找”以区别于其他可能的最小Linux实现,例如busybox。 :)
– dannysauer
20-2-23在4:12
#7 楼
请使用rm -rf directory
而不是rm -rf *
。但是随后,我们的一位高级工程师建议我们避免使用星号(rm -rf *
),而应将其传递给父目录,例如*
。 经过一番激烈的辩论之后,我们决定对它进行基准测试,以及使用
rm -rf directory
的第三种方法。结果如下:time rm -rf * 2m17.32s
time rm -rf directory 0m15.60s
time find directory -delete 0m16.97s
find
比rm -rf directory
快9倍!不用说,我们买了工程师啤酒!
所以现在我们使用
rm -rf *
删除目录并重新创建。评论
问题是*进行了shell扩展,这意味着:(a)读取整个目录,然后(b)甚至在调用find之前对所有文件名进行排序。使用ls -1 -U以串行顺序读取目录。您可以输入-n 10000并获取要发送到xargs rm的列表。并且由于这些名称在目录的第一部分都是串行的,因此它们也被有效地删除。只需将其循环,直到没有剩余文件,它就会很好地工作。
– Paul_Pedant
19年11月15日在21:05
感谢@Paul_Pedant的推理!
–约书亚·品特(Joshua Pinter)
19年11月15日在21:21
#8 楼
关于上面的-delete
选项:我正在使用它删除我创建的temp文件夹中的大量(1M + est)文件,并且无意中忘记了每晚进行清理。我不小心填充了磁盘/分区,除find .
命令外,其他都无法删除它们。它很慢,起初我使用的是:find . -ls -exec rm {} \;
但这要花费大量时间。它大约在15分钟后开始删除某些文件,但是我猜测它在最终启动后每秒删除的速度不到10左右。因此,我尝试了:
find . -delete
,我现在就让它运行。它看起来运行得更快,尽管它在CPU上的工作量极高,而其他命令却没有。它已经运行了大约一个小时,我想我的驱动器上的空间已经恢复了,分区逐渐“缩小”,但是仍然需要很长时间。我严重怀疑它的运行速度比其他设备快1000倍。在所有情况下,我只想指出空间与时间之间的权衡。如果您有空闲的CPU带宽(我们愿意),请运行后者。我的CPU正在运行(
uptime
报告):通常负载很轻,几个小时就可以了。我已经检查了系统上的大多数其他内容,但它们仍然可以响应,因此我们现在可以了。评论
如果要使用exec,则几乎可以肯定不使用-ls并执行find。 -type f -exec rm'{}'+ +更快,因为它将为rm提供尽可能多的参数。
– xenoterracide
2014年1月3日,17:48
我认为您应该继续进行编辑并将其编辑为自己的答案...评论实在太久了。而且,听起来您的文件系统具有相当昂贵的删除功能,您好奇它是哪一个?您可以通过nice或ionice运行该find ...- delete,这可能会有所帮助。因此,可能会将某些安装选项更改为不太安全的设置。 (当然,取决于文件系统上的其他内容,删除所有内容的最快方法通常是mkfs。)
–德罗伯特
2014年1月4日7:24
平均负载并不总是CPU,它只是随时间推移阻塞进程数的度量。进程可能会阻塞磁盘I / O,这很可能在这里发生。
–Score_Under
14年7月14日在12:47
另请注意,平均负载并未考虑逻辑CPU的数量。因此,单核计算机的loadavg 1与64核系统上的loadavg 64相同-意味着每个CPU 100%的时间都处于繁忙状态。
– Marki555
15年6月29日在12:49
#9 楼
考虑使用Btrfs卷,只需为包含大量文件的目录删除整个卷即可。 br />#10 楼
有几种方法可用于删除linux中的大量文件。您可以将find与delete选项一起使用,这比exec选项要快。然后您可以使用perl取消链接,甚至可以使用rsync。如何在linux中删除大量文件
#11 楼
假设已安装GNUparallel
,我已经使用了它:parallel rm -rf dir/{} ::: `ls -f dir/`
它足够快。
#12 楼
正如我从本站点中学到的那样,删除REALLY LARGE目录需要一种不同的方法-您需要利用ionice,它可以确保-c3删除仅在系统具有IO时间的情况下执行。您的系统负载不会增加到很高,并且所有内容都保持响应(尽管我的CPU查找时间相当长,大约为50%)。find <dir> -type f -exec ionice -c3 rm {} \;
评论
用+代替\;一次将更多的参数传递给rm时,将使此过程更快,减少分叉
– xenoterracide
2014年1月3日17:50
为什么不ionice -c3找到
– jtgd
18-10-27在12:57
#13 楼
如果您有数百万个文件,并且上述每个解决方案都使您的系统处于压力之下,则可以尝试以下启发:nice_delete
文件:现在删除文件:#!/bin/bash
MAX_LOAD=3
FILES=("$@")
BATCH=100
while [ ${#FILES[@]} -gt 0 ]; do
DEL=("${FILES[@]:0:$BATCH}")
ionice -c3 rm "${DEL[@]}"
echo -n "#"
FILES=("${FILES[@]:$BATCH}")
while [[ $(cat /proc/loadavg | awk '{print int()}') -gt $MAX_LOAD ]]; do
echo -n "."
sleep 1
done
done
查找将创建约数万个文件的批处理(请参阅
getconf ARG_MAX
)并将其传递给nice_delete
。这将创建更小的批次,以在检测到过载时允许睡眠。#14 楼
ls -1 | xargs rm -rf
应在主文件夹中工作
评论
由于文件夹中的文件数量过多,ls无法正常工作。这就是为什么我不得不使用find的原因,谢谢。
–托比
2012年4月26日在8:19
@Toby:尝试使用ls -f禁用排序。排序要求将整个目录加载到要排序的内存中。未排序的ls应该能够流式传输其输出。
– camh
2012年4月26日上午10:59
不适用于包含换行符的文件名。
–maxschlepzig
2014年1月5日7:53
@camh是真的。但是,按排序顺序删除文件要比按未排序顺序删除文件更快(因为每次删除后都要重新计算目录的btree)。请参阅此答案以获取示例serverfault.com/a/328305/105902
– Marki555
2015年6月29日12:50
@maxschlepzig用于此类文件,您可以使用find。 -print0 | xargs -0 rm,它将使用NULL char作为文件名分隔符。
– Marki555
15年6月29日在12:51
#15 楼
对于上述Izkata的提示:但这确实有效:工作-但是我在许可方面遇到了一些问题;文件在服务器上,但是我仍然不知道此权限问题来自何处。无论如何,终端要求对每个文件进行确认。文件数量约为20000,因此这不是一个选择。在“ -r”之后,我添加了选项“ -f”,因此整个命令为“ rm -r -f foldername /”。然后它似乎工作正常。我是Terminal的新手,但我想这还好吧?谢谢!
#16 楼
根据您需要如何清除这些文件,我建议使用shred
。如果要清除目录,则不能使用q4312079q。删除它并重新创建它,我建议将其移动并立即重新创建。切记:您无法真正在多核计算机上并行化此测试。它取决于磁盘访问,而磁盘访问受RAID或您所拥有的限制。
评论
shred无法与许多现代文件系统一起使用。
–user26112
2013年7月2日14:47
#17 楼
如果您只想尽快清除许多文件,则ls -f1 /path/to/folder/with/many/files/ | xargs rm
可能会正常工作,但最好不要在生产系统上运行它,因为您的系统可能会成为IO问题,并且在删除操作期间应用程序可能会卡住。此脚本可很好地用于许多文件,并且不应影响系统的ioload。
#!/bin/bash
# Path to folder with many files
FOLDER="/path/to/folder/with/many/files"
# Temporary file to store file names
FILE_FILENAMES="/tmp/filenames"
if [ -z "$FOLDER" ]; then
echo "Prevented you from deleting everything! Correct your FOLDER variable!"
exit 1
fi
while true; do
FILES=$(ls -f1 $FOLDER | wc -l)
if [ "$FILES" -gt 10000 ]; then
printf "[%s] %s files found. going on with removing\n" "$(date)" "$FILES"
# Create new list of files
ls -f1 $FOLDER | head -n 5002 | tail -n 5000 > "$FILE_FILENAMES"
if [ -s $FILE_FILENAMES ]; then
while read FILE; do
rm "$FOLDER/$FILE"
sleep 0.005
done < "$FILE_FILENAMES"
fi
else
printf "[%s] script has finished, almost all files have been deleted" "$(date)"
break
fi
sleep 5
done
#18 楼
使用ls -f | xargs -n 5000 rm
,同时调整-n
的批次大小以适合您的系统(对于-n
提示,请使用@digital_infinity表示感谢)。另外,您还可以使用内联grep过滤列表,例如ls -f | grep '^156' | xargs -n 5000 rm
。根据我的经验,这比使用find的技术快得多,并且消除了对更复杂的shell脚本的需求。
#19 楼
Python脚本不应该被认为是不干净的:从我的实验来看,它似乎还不错。可以处理NB错误以至少将它们打印出来...但是之后运行
trash myDirectoryForDeletion
或rm -rfv myDirectoryForDeletion
可能会更简单。
评论
文件夹中的rm -rf *可能由于参数过多而失败;但是如果您仍然要删除整个目录,那么rm -rf folder /呢?建议不要将该文件夹放在一个单独的分区上,而只需手动卸载&&格式化&&重新安装。
出于好奇-破解rm -rf需要多少文件?
您可能应该将问题重命名为更准确的名称,例如“有效删除包含数千个文件的大型目录”。为了删除目录及其内容,根据定义,必须进行递归。您可以手动将目录inode本身本身手动断开链接(可能需要root特权),卸载文件系统,然后在其上运行fsck来回收未使用的磁盘块,但是这种方法似乎有风险,而且可能不会更快。此外,文件系统检查可能仍涉及以递归方式遍历文件系统树。
一旦我的ccache文件树变得如此巨大,并且rm花费了如此长的时间(并使整个系统呆滞),从文件系统中复制所有其他文件,格式化并复制回它们的速度就快得多。从那时起,我给如此庞大的小文件树提供了自己的专用文件系统,因此您可以直接使用mkfs代替rm。