我知道像
这样的命令find <dir> -type f -exec rm {} \;
不是删除大量文件的最佳变体(总文件,包括子文件夹)。如果您有少量文件,它会很好用,但如果您在子文件夹中有10+ mlns文件,它可以挂起服务器。
有没有人知道任何特定的linux命令来解决这个问题?
答案 0 :(得分:7)
看起来很奇怪,但是:
$ rm -rf <dir>
答案 1 :(得分:5)
以下是bash脚本示例:
#!/bin/bash
local LOCKFILE=/tmp/rmHugeNumberOfFiles.lock
# this process gets ultra-low priority
ionice -c2 -n7 -p $$ > /dev/null
if [ $? ]; then
echo "Could not set disk IO priority. Exiting..."
exit
fi
renice +19 -p $$ > /dev/null
if [ $? ]; then
echo "Could not renice process. Exiting..."
exit
fi
# check if there's an instance running already. If so--exit
if [ -e ${LOCKFILE} ] && kill -0 `cat ${LOCKFILE}`; then
echo "An instance of this script is already running."
exit
fi
# make sure the lockfile is removed when we exit. Then: claim the lock
trap "command rm -f -- $LOCKFILE; exit" INT TERM EXIT
echo $$ > $LOCKFILE
# also create a tempfile, and make sure that's removed too upon exit
tmp=$(tempfile) || exit
trap "command rm -f -- '$tmp'" INT TERM EXIT
# ----------------------------------------
# option 1
# ----------------------------------------
# find your specific files
find "$1" -type f [INSERT SPECIFIC SEARCH PATTERN HERE] > "$tmp"
cat $tmp | rm
# ----------------------------------------
# option 2
# ----------------------------------------
command rm -r "$1"
# remove the lockfile, tempfile
command rm -f -- "$tmp" $LOCKFILE
此脚本首先将自己的进程优先级和diskIO优先级设置为非常低的值,以确保其他正在运行的进程尽可能不受影响。
然后它确保它是唯一运行的进程。
脚本的核心非常符合您的偏好。如果您确定可以毫不含糊地删除整个目录(选项2),则可以使用rm -r
,或者可以使用find
删除更具体的文件(选项1,可能使用命令行选项“$ 2 “为方便起见。”
在上面的实现中,选项1(find
)首先将所有内容输出到临时文件,以便rm
函数仅被称为一次而不是在找到每个文件之后按find
。当文件数量确实很大时,这可以节省大量时间。在缺点方面,临时文件的大小可能会成为一个问题,但这只有在您删除数十亿个文件时才会发生这种情况,而且,因为diskIO具有如此低的优先级,使用临时文件后跟一个{{1}可能总比使用rm
选项慢。与往常一样,您应该尝试一下,看看哪种最适合您的需求。
编辑:根据user946850的建议,您也可以跳过整个临时文件并使用
find (...) -exec rm {} \;
。这具有更大的内存占用,因为所有匹配文件的所有完整路径都将插入RAM中,直到find (...) -print0 | xargs -0 rm
命令完全完成。从好的方面来说:由于写入临时文件,没有额外的文件IO。选择哪一个取决于您的用例。
答案 2 :(得分:1)
-r
(递归)开关也会删除目录下的所有内容 - 包括子目录。 (您的命令不会删除目录,只删除文件。)
您还可以加快find
方法:
find -type f -print0 | xargs -0 rm
答案 3 :(得分:0)
我尝试了这些命令中的每一个,但问题是删除过程是锁定磁盘,并且由于没有其他进程可以访问它,因此有大量进程试图访问磁盘使问题变得更糟。运行“iotop”,查看您的进程使用的磁盘IO数量。
这是解决我的问题的python脚本。它一次删除500个文件,然后休息2秒让其他进程开展业务,然后继续。
import os, os.path
import time
for root, dirs, files in os.walk('/dir/to/delete/files'):
i = 0
file_num = 0
for f in files:
fullpath = os.path.join(root, f)
i = i + 1
file_num = file_num + 1
os.remove(fullpath)
if i%500 == 1:
time.sleep(2)
print "Deleted %i files" % file_num
希望这可以帮助一些人。
答案 4 :(得分:0)
如果你需要在一个非常大的文件树上处理空间限制问题(在我的情况下很多perforce分支),有时在运行时被挂起查找和删除过程 -
这是我每天安排的脚本查找具有特定文件的所有目录(“ChangesLog.txt”), 然后排序所有目录 早于 2天,并删除第一个匹配的目录(每个计划可能有新匹配):
bash -c "echo @echo Creating Cleanup_Branch.cmd on %COMPUTERNAME% - %~dp0 > Cleanup_Branch.cmd"
bash -c "echo -n 'bash -c \"find ' >> Cleanup_Branch.cmd"
rm -f dirToDelete.txt
rem cd. > dirToDelete.txt
bash -c "find .. -maxdepth 9 -regex ".+ChangesLog.txt" -exec echo {} >> dirToDelete.txt \; & pid=$!; sleep 100; kill $pid "
sed -e 's/\(.*\)\/.*/\1/' -e 's/^./"&/;s/.$/&" /' dirToDelete.txt | tr '\n' ' ' >> Cleanup_Branch.cmd
bash -c "echo -n '-maxdepth 0 -type d -mtime +2 | xargs -r ls -trd | head -n1 | xargs -t rm -Rf' >> Cleanup_Branch.cmd"
bash -c 'echo -n \" >> Cleanup_Branch.cmd'
call Cleanup_Branch.cmd
注意要求:
答案 5 :(得分:0)
如果你有一个相当现代的find版本(4.2.3或更高版本),你可以使用-delete标志。
find <dir> -type f -delete
如果您使用的是4.2.12或更高版本,则可以通过\+
-exec修饰符利用xargs样式命令行堆叠。这样,您就不会为每个文件运行/bin/rm
的单独副本。
find <dir> -type f -exec rm {} \+
答案 6 :(得分:0)
之前的命令很好。
对于一个文件夹中的十亿个文件, rm -rf directory/
也可以更快地运行。我试过了。
答案 7 :(得分:0)
您可以创建一个空目录并将其RSYNC到您需要清空的目录。 你将避免超时和记忆问题
答案 8 :(得分:0)
如果您想尽快删除大量文件,请尝试以下操作:
find . -type f -print0 | xargs -P 0 -0 rm -f
请注意,-P
选项会使xargs
尽可能多地使用流程。