UNIX のディレクトリの下に数百の PDF があります。PDF の名前は非常に長い (約 60 文字)。
次のコマンドを使用してすべての PDF をまとめて削除しようとすると:
rm -f *.pdf
次のエラーが表示されます。
/bin/rm: cannot execute [Argument list too long]
このエラーの解決策は何ですか? このエラーはmv
およびcp
コマンドでも発生しますか? はいの場合、これらのコマンドを解決する方法は?
UNIX のディレクトリの下に数百の PDF があります。PDF の名前は非常に長い (約 60 文字)。
次のコマンドを使用してすべての PDF をまとめて削除しようとすると:
rm -f *.pdf
次のエラーが表示されます。
/bin/rm: cannot execute [Argument list too long]
このエラーの解決策は何ですか? このエラーはmv
およびcp
コマンドでも発生しますか? はいの場合、これらのコマンドを解決する方法は?
これが発生する理由は、bash が実際にすべての一致するファイルにアスタリスクを展開し、非常に長いコマンド ラインを生成するためです。
これを試して:
find . -name "*.pdf" -print0 | xargs -0 rm
警告:これは再帰的な検索であり、サブディレクトリ内のファイルも検索 (および削除) します。-f
確認が不要であることが確実な場合にのみ、rm コマンドを使用してください。
コマンドを非再帰的にするには、次のようにします。
find . -maxdepth 1 -name "*.pdf" -print0 | xargs -0 rm
別のオプションは、find の-delete
フラグを使用することです。
find . -name "*.pdf" -delete
find
アクションがあり-delete
ます:
find . -maxdepth 1 -name '*.pdf' -delete
別の答えはxargs
、コマンドをバッチで強制的に処理することです。たとえば、一度にdelete
ファイルをディレクトリに移動し、これを実行します。100
cd
echo *.pdf | xargs -n 100 rm
または、次を試すことができます。
find . -name '*.pdf' -exec rm -f {} \;
あなたはこれを試すことができます:
for f in *.pdf
do
rm "$f"
done
編集: ThiefMaster のコメントは、そのような危険な行為を若いシェルのジェダイに開示しないことを示唆しているため、より「安全な」バージョンを追加します (誰かが「-rf . ..pdf」ファイルを持っている場合に物事を保存するため)。
echo "# Whooooo" > /tmp/dummy.sh
for f in '*.pdf'
do
echo "rm -i \"$f\""
done >> /tmp/dummy.sh
上記を実行した後、お気に入りのエディターでファイルを開き、/tmp/dummy.sh
危険なファイル名がないかすべての行をチェックし、見つかった場合はコメントアウトします。
dummy.sh
次に、スクリプトを作業ディレクトリにコピーして実行します。
これはすべてセキュリティ上の理由によるものです。
あなたはこの褒め言葉を使うことができます
find -name "*.pdf" -delete
rmコマンドには、同時に削除できるファイルの制限があります。
次のようなファイルパターンに基づいて、 rmコマンドを複数回使用してそれらを削除できる可能性があります。
rm -f A*.pdf
rm -f B*.pdf
rm -f C*.pdf
...
rm -f *.pdf
findコマンドを使用してそれらを削除することもできます。
find . -name "*.pdf" -exec rm {} \;
そしてもう一つ:
cd /path/to/pdf
printf "%s\0" *.[Pp][Dd][Ff] | xargs -0 rm
printf
シェルの組み込みであり、私が知る限り、それは常にそうでした。printf
これがシェル コマンドではなく (組み込み) であることを考えると、" argument list too long ...
" 致命的なエラーの影響を受けません。
そのため、などのシェル グロビング パターンで安全に使用できます*.[Pp][Dd][Ff]
。次に、その出力を を介して remove( rm
) コマンドにパイプしますxargs
。これにより、コマンドが失敗しないように、コマンド ラインに十分なファイル名が収まるようになりますrm
。これはシェルです。指図。
\0
inは、コマンドによって処理されるファイル名のヌル区切り文字として機能し、区切り文字として ( ) を使用するためprintf
、ファイル名に空白やその他の特殊文字が含まれていても失敗しません。xargs
-0
rm
スペースまたは特殊文字を含むファイル名の場合は、次を使用します。
find -name "*.pdf" -delete
現在のディレクトリ内のファイルのみ:
find -maxdepth 1 -name '*.pdf' -delete
この文は、現在のディレクトリ (-maxdepth 1) 内の拡張子 pdf (-name '*.pdf') を持つすべてのファイルを検索し、削除します。
フォームのソースディレクトリを宛先にコピーしているときに同じ問題に直面していました
ソースディレクトリにはファイルがありました ~3 lakcs
オプション-rでcpを使用しましたが、うまくいきました
cp -r abc/def/
引数リストが長すぎるという警告を出さずに、すべてのファイルをabcからdefにコピーします
*.pdf
ディレクトリ内のすべてを削除するには/path/to/dir_with_pdf_files/
mkdir empty_dir # Create temp empty dir
rsync -avh --delete --include '*.pdf' empty_dir/ /path/to/dir_with_pdf_files/
rsync
何百万ものファイルがある場合、ワイルドカードを使用して特定のファイルを削除するのがおそらく最速のソリューションです。そして、あなたが得ているエラーを処理します。
(オプションのステップ): DRY RUN。削除せずに削除されるものを確認するには。`
rsync -avhn --delete --include '*.pdf' empty_dir/ /path/to/dir_with_pdf_files/
. . .
より多くの rsync ハックについては、rsync のヒントとコツをクリックしてください
時間がない人向け。 ターミナルで次のコマンドを実行します。
ulimit -S -s unlimited
次に、cp/mv/rm 操作を実行します。
私はこれを回避する方法しか知りません。アイデアは、持っているpdfファイルのリストをファイルにエクスポートすることです。次に、そのファイルをいくつかの部分に分割します。次に、各パートにリストされている pdf ファイルを削除します。
ls | grep .pdf > list.txt
wc -l list.txt
wc -l は、list.txt に含まれる行数をカウントすることです。どれくらいの長さかがわかったら、半分に分割するか、4つに分割するかを決めることができます. split -l コマンドを使用する たとえば、600 行ごとに分割します。
split -l 600 list.txt
これにより、分割方法に応じて、xaa、xab、xac などの名前のファイルがいくつか作成されます。これらのファイルの各リストをコマンド rm に「インポート」するには、次のようにします。
rm $(<xaa)
rm $(<xab)
rm $(<xac)
私の悪い英語でごめんなさい。
すべての inode をいっぱいにするアプリケーションによって作成された何百万もの役に立たないログ ファイルがあったとき、私は同様の問題に直面しました。私は「検索」に頼り、「検索」されたすべてのファイルをテキストファイルに取得してから、それらを1つずつ削除しました。少し時間がかかりましたが、仕事をしました!
私はこの問題に数回遭遇しました。ソリューションの多くは、rm
削除する必要がある個々のファイルごとにコマンドを実行します。これは非常に非効率的です:
find . -name "*.pdf" -print0 | xargs -0 rm -rf
ファイル名の最初の 4 文字に基づいてファイルを削除する Python スクリプトを作成しました。
import os
filedir = '/tmp/' #The directory you wish to run rm on
filelist = (os.listdir(filedir)) #gets listing of all files in the specified dir
newlist = [] #Makes a blank list named newlist
for i in filelist:
if str((i)[:4]) not in newlist: #This makes sure that the elements are unique for newlist
newlist.append((i)[:4]) #This takes only the first 4 charcters of the folder/filename and appends it to newlist
for i in newlist:
if 'tmp' in i: #If statment to look for tmp in the filename/dirname
print ('Running command rm -rf '+str(filedir)+str(i)+'* : File Count: '+str(len(os.listdir(filedir)))) #Prints the command to be run and a total file count
os.system('rm -rf '+str(filedir)+str(i)+'*') #Actual shell command
print ('DONE')
これは私にとって非常にうまくいきました。フォルダー内の 200 万を超える一時ファイルを約 15 分で消去することができました。Python の知識がほとんどない、またはまったくない人でもこのコードを操作できるように、少しのコードから tar をコメントアウトしました。
GNU parallel( sudo apt install parallel
) の使用は非常に簡単です
コマンドをマルチスレッドで実行します。'{}' は渡された引数です。
例えば
ls /tmp/myfiles* | parallel 'rm {}'