
""区切り文字付きのテキストファイルでリンクされた非常に小さなファイルで構成される非常に大きなアーカイブがあります。小さなアーカイブの場合は、パターンをsplit
「」を使用してアーカイブし、結果ファイルを処理します。ただし、このアーカイブには約1億のファイルがあります。 1つのディレクトリにすべて入れるには多すぎるようです。作成したディレクトリにフォルダなどを移動するためのフォルダなどを作成しましたaa
。ab
しかし、問題が発生しました。私が試したこと:
split
結果ファイルに対してコマンドを実行するコマンドはありません。だから手でしなければなりませんでした。**
ファイルをディレクトリに移動することは、ファイルが行の末尾にないfind . -name "xaa*" -exec mv {} aa \+
ため機能しません。{}
-t
私のUnixバージョンでは、ソースとターゲットを反転させるフラグを使用することはできません。find
xargs
これが機能するには、出力をパイプで接続する必要があります。
しかし、これは遅すぎます。ファイルが移動できるよりもはるかに速く生成されます。
xargs
afterを使用するよりも一度に処理されるファイル数が\+
少ないようですfind -exec
。一度に6000個のエントリを実行するために「-R 6000」フラグを追加しようとしましたが、これには違いはありません。split
優先順位をできるだけ下げます。消費するCPUの量は変更されていないため、影響はありません。コマンドを実行するために最大7つのコマンドプロンプト(各コマンドプロンプトの最後の4文字)を開き
mv
ましたが、まだ十分ではありませんでした。もっと開いてみたかったのですが、システムが7つに達すると応答が遅すぎて分割を停止する必要がありました。たとえば、コマンドが何かを返すのを待っている間、ls -l | tail
ソースアーカイブはUSBにコピーされます。
だから私がしたことは、split
この時点で停止し、mv
コマンドが続くのを待ってから分割を再開することです。その時は、
find -exec rm {} \+
すでに持っているファイルを削除するのに少し早いので、私が持っていないファイルに到達すると、その周辺にファイルが少なくなります。
したがって、最初の反復は約300万ファイル、次の約200万ファイル、次の約1.5ファイルの間続きました。しかし、より良い方法があると確信しています。試してみる他のアイデアはありますか?
答え1
このような操作は入力行ごとに1回実行されますxargs -I {} ... mv {} aa
。mv
~からPOSIX仕様-I
オプションxargs
:
Insert mode: utility is executed for each logical line from standard input.
実際には、複数のファイルに対して単一のファイルを実行するにはxargs -r sh -c 'mv "$@" aa' _
(またはその時点で)同じものが必要です。このようにして、シェルを使用してターゲットディレクトリ間にパラメータを挿入できます。find ... -exec sh -c 'mv "$@" aa' _ {} +
mv
mv
"$@"
フィールド分割やワイルドカードなしですべての引数を使用してシェルに置き換えられました。- 指定されたスクリプトと同じ効果があります
_
。次のパラメータは等しいか集合的です。$0
sh -c
$1
$2
$@
それにもかかわらず、私はあなたがfind
競争条件に参加すると思います。完了する前にディレクトリリストの読み取りを完了できるため、split
すべてのファイルを処理できない場合があります。また、作成したサブディレクトリに繰り返し移動し、以前にそこに移動したファイルを検出して再度移動しようとすると、aa/xaa
エラーが発生する可能性がありますaa/
(ただし、-exec ... {} +
コマンドの終了ステータスは無視されます)。