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

このスクリプトは、他の実行中のプロセスが可能な限り影響を受けないようにするために、独自のプロセス優先度とdiskIO優先度を非常に低い値に設定することから始まります。

次に、それが実行されている唯一のそのようなプロセスであることを確認します。

スクリプトのコアは本当にあなたの好み次第です。rm -rdir全体を無差別に削除できることが確実な場合に使用できます(オプション2)。またはfind、より具体的なファイル削除に使用できます(オプション1、コマンドラインオプション "$ 2"およびonw。を使用する場合があります)。

上記の実装では、オプション1(find)は最初にすべてを一時ファイルに出力するため、rm関数は、によって検出された各ファイルの後ではなく、1回findだけ呼び出されます。ファイルの数が実際に膨大な場合、これは大幅な時間の節約になります。欠点としては、一時ファイルのサイズが問題になる可能性がありますが、これは文字通り数十億のファイルを削除する場合にのみ発生する可能性があります。さらに、diskIOの優先度が非常に低いため、一時ファイルの後に1つを使用するrmと合計でfind (...) -exec rm {} \;オプションを使用するよりも遅い。いつものように、少し実験して、ニーズに最適なものを確認する必要があります。

編集:user946850によって提案されているように、一時ファイル全体をスキップしてを使用することもできますfind (...) -print0 | xargs -0 rmfindコマンドが完全に終了するまで、一致するすべてのファイルへのすべてのフルパスがRAMに挿入されるため、これはメモリフットプリントが大きくなります。利点:一時ファイルへの書き込みによる追加のファイルIOはありません。どちらを選択するかは、ユースケースによって異なります。

于 2012-07-06T10:52:48.670 に答える
1

-r再帰的)スイッチは、サブディレクトリを含む、ディレクトリの下のすべても削除します。(コマンドはディレクトリを削除せず、ファイルのみを削除します。)

findアプローチをスピードアップすることもできます。

find -type f -print0 | xargs -0 rm
于 2012-07-05T07:22:55.887 に答える
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でOSコマンドを直接呼び出す。それ以外の場合は、Windowsのデフォルトコマンドを使用していたため。
  3. 検索結果を保存するために、削除するディレクトリを外部テキストファイルに収集します。これは、検索プロセスがハングすることがあるためです。
  4. 100秒後に強制終了されるバックグラウンドプロセスを使用して、検索プロセスにタイムアウトを設定します。
  5. 削除の優先順位について、最も古いディレクトリを最初に並べ替えます。
于 2013-07-08T13:19:14.913 に答える
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/また、1つのフォルダー内の数十億のファイルに対してより高速に動作します。やってみました。

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