7

据我所知,命令如

find <dir> -type f -exec rm {} \;

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

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

4

10 回答 10

8

这可能看起来很奇怪,但是:

$ rm -rf <dir>
于 2012-07-05T07:23:06.093 回答
6

这是一个示例 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

该脚本首先将自己的进程优先级和磁盘IO 优先级设置为非常低的值,以确保其他正在运行的进程尽可能不受影响。

然后它确保它是唯一运行的此类进程。

脚本的核心完全取决于您的喜好。如果您rm -r确定可以随意删除整个目录(选项 2),则可以使用,或者您可以find用于更具体的文件删除(选项 1,可能使用命令行选项“$2”和 onw。为方便起见)。

在上面的实现中,选项 1 ( find) 首先将所有内容输出到一个临时文件,因此该rm函数仅被调用一次,而不是在find. 当文件数量确实很大时,这可以节省大量时间。不利的一面是,临时文件的大小可能会成为一个问题,但这仅在您要删除数十亿个文件时才有可能,另外,由于 diskIO 的优先级如此之低,因此使用一个临时文件后跟一个单个文件rm可能总共是比使用find (...) -exec rm {} \;选项慢。与往常一样,您应该进行一些试验,看看最适合您的需求。

编辑:根据 user946850 的建议,您也可以跳过整个临时文件并使用find (...) -print0 | xargs -0 rm. 这具有更大的内存占用,因为所有匹配文件的所有完整路径都将插入 RAM 中,直到find命令完全完成。好的一面是:由于写入临时文件,没有额外的文件 IO。选择哪一个取决于您的用例。

于 2012-07-06T10:52:48.670 回答
1

-r递归)开关也删除目录下的所有内容 - 包括子目录。(您的命令不会删除目录,只会删除文件。)

您还可以加快find方法:

find -type f -print0 | xargs -0 rm
于 2012-07-05T07:22:55.887 回答
0

如果您有相当现代的 find 版本(4.2.3 或更高版本),您可以使用 -delete 标志。

find <dir> -type f -delete

\+如果您有 4.2.12 或更高版本,则可以通过-exec 修饰符利用 xargs 样式的命令行堆栈。这样您就不会/bin/rm为每个文件运行单独的副本。

find <dir> -type f -exec rm {} \+
于 2013-07-17T17:59:11.787 回答
0

前面的命令很好。

rm -rf directory/也可以更快地处理一个文件夹中的数十亿个文件。我试过了。

于 2014-04-15T14:29:32.130 回答
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

希望这可以帮助一些人。

于 2012-12-23T15:26:27.467 回答
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. 通过使用 & 在 100 秒后被杀死的后台进程设置查找进程的超时。
  5. 首先对最旧的目录进行排序,以获得删除优先级。
于 2013-07-08T13:19:14.913 回答
0

如果您想尽快删除大量文件,请尝试以下操作:

find . -type f -print0 | xargs -P 0 -0 rm -f

请注意,该-P选项将xargs尽可能多地使用进程。

于 2017-07-21T01:52:47.660 回答
0
mv large_folder /tmp/.
sudo reboot

调用 mv 很快——它只是修改标签。系统重新启动将以最快的方式清除 /tmp 文件夹(再次挂载它?)。

于 2021-12-01T16:03:56.420 回答
-1

您可以创建一个空目录并将其 RSYNC 到您需要清空的目录。您将避免超时和内存不足的问题

于 2016-08-29T09:35:23.640 回答