私はCentOSサーバーで作業しており、何百万ものファイルを移動してまとめる必要があります。私は以下のようなものの多くの化身を試しましたが、それらはすべて引数リストが長すぎるエラーで失敗します。
コマンド:
find ./ -iname out.* -type f -exec mv {} /home/user/trash
find ./paramsFile.* -exec cat > parameters.txt
エラー:
-bash: /usr/bin/find: Argument list too long
-bash: /bin/cat: Argument list too long
または
echo ./out.* | xargs -I '{}' mv /home/user/trash
(echo ./paramsFile.* | xargs cat) > parameters.txt
エラー:
xargs: argument line too long
xargs: argument line too long
2番目のコマンドも終了しませんでした。グロブについていくつか聞いたことがありますが、完全に理解できるかどうかはわかりません。ヒントや提案は大歓迎です!
あなたには複数の間違いがあります。 *
グロブをエスケープする必要があります。 (ファイル名のセキュリティのために)引用符の間に{}
を入れ、-exec
を\;
で終了する必要があります。
find ./ -iname out.\* -type f -exec mv "{}" /home/user/trash \;
find -name ./paramsFile.\* -exec cat "{}" >> parameters.txt \;
ここでの問題は、*
がディレクトリ内のすべてのファイルと一致しているため、エラーが発生することです。 find
がシェルグロブの代わりにファイルを見つけた場合、xargs
は、正しい長さの行を作成するために使用できる個々のファイル名を取得します。
これを試して:
find . -iname 'out.*' -type f -exec mv '{}' /home/user/trash \;
find . -name 'paramsFile.*' -print0 | xargs -0 cat >> parameters.txt
>>
は、以前の呼び出しの結果を上書きせずに、cat
の複数の呼び出し(実際に膨大な数のファイルがある場合)が同じファイルに出力されるようにすることです。また、parameters.txt
は空から始まります(または最初に削除します)。
現時点では、非常に良い(つまりテスト済みの)答えを出すのに便利なボックスはありませんが、これは parallel
の良い使い方だと思います。
私が正しく理解していれば、あなたの命令
find ./ -iname out.* -type f -exec mv "{}" /home/user/trash
1つの巨大なコマンドを作成しています:
mv out.1 out.2 out.3 out.4 ... out.10100942 /home/user/trash
代わりに、
find ./ -iname out.* -type f | parallel mv "{}" /home/user/trash
何百万もの小さなコマンドを実行します:
mv out.1 /home/user/trash
mv out.2 /home/user/trash
...
parallel
のオプションのいくつか、具体的には -j
および-i
サーバーが予期せず過負荷にならないようにします。
PS。 @Bernhardのアドバイスに従ってください。特にユーザー入力にシェル変数を使用する場合は、引用してください。行う "{}"
ではない{}
。