删除包含数千个文件的大型目录的最佳和最快方法是什么(在ubuntu中)

时间:2012-07-05 07:19:52

标签: linux bash

我知道像

这样的命令
find <dir> -type f -exec rm {} \;

不是删除大量文件的最佳变体(总文件,包括子文件夹)。如果您有少量文件,它会很好用,但如果您在子文件夹中有10+ mlns文件,它可以挂起服务器。

有没有人知道任何特定的linux命令来解决这个问题?

9 个答案:

答案 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

注意要求:

  1. 仅删除带有“ChangesLog.txt”的目录,因为不应删除其他旧目录。
  2. 直接在 cygwin 中调用操作系统命令,否则它会使用Windows默认命令。
  3. 将要删除的目录收集到外部文本文件中,以便保存查找结果,因为有时查找过程已被挂起。
  4. 使用&amp ;;为查找过程设置超时100秒后被杀的背景过程
  5. 首先对最早的目录进行排序,以获取删除优先级。

答案 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尽可能多地使用流程。