
各ファイルがサブフォルダに配置されている 1 つのディレクトリ ツリーから、「300 MB」を超えるファイルを移動したい
例: ディレクトリ構造は次のようになります:
dirA/
dirA/file1
dirA/x/
dirA/x/file2
dirA/y/
dirA/y/file3
予想される結果は、各ファイルがサブフォルダーに移動されるディレクトリ ツリーの「移動」です。
dirB/ # normal directory
dirB/file1 # moved from dirA/file1
dirB/x/ # normal directory
dirB/x/file2 # moved from dirA/x/file2
dirB/y/ # normal directory
dirB/y/file3 # moved from dirA/y/file3
しかしfind /path/ -type f -size +300m
、その後はどうなりますか? 残念ながら、一部のファイルには、キーボードで見つけられるあらゆる種類の文字が含まれています。
私はこれを見てきました糸誰かが話しているのですcpio
が、私はそのプログラムを知りません...
PS: GNU Parallel をインストールしておけば、処理速度が上がるかもしれません。
答え1
簡単な方法は翻訳. 使用することができますglob 修飾子種類やサイズなどの基準に従ってファイルを照合します。ワイルドカードパターン **/
任意のレベルのサブディレクトリに一致します。履歴修飾子 h
および は、t
ディレクトリとファイル名のベース部分を抽出する簡単な方法です。mkdir -p
必要に応じて を呼び出してディレクトリを作成します。
cd dirA
for x in **/*(.Lm+300); do
mkdir -p ../dirB/$x:h &&
mv -- $x ../dirB/$x
done
移植可能な方法は を使用することですfind
。 を使用して-exec
、ファイルごとにシェル スニペットを呼び出します。
cd dirA
find . -type f -size +300000k -exec sh -c 'for x do
mkdir -p "../dirB/${x%/*}"
mv "$x" "../dirB/$x"
done' sh {} +
並列化は入出力にはほとんど役に立ちません。並列化により複数の CPU を活用できますが、CPU が I/O のボトルネックになることはほとんどありません。
答え2
Perlは当然の選択です。 、、rename
としてインストールできます。ren
rename
pren
find dirA -type f -size +300M | ren 's:^dirA/:dirB/:'
ただし、ファイルが別のマウント ポイントに移動されている場合は機能せず、ディレクトリが存在しない場合は失敗します。
GNU Parallel は遅くなります:
cd dirA
find . -type f -size +300M | parallel mkdir -p ../dirB/{//}
find . -type f -size +300M | parallel mv {} ../dirB/{}
ただし、ファイルを別のファイル システムに移動するためにコピーしてから削除するルーチンを実行する必要がある場合でも機能します。
答え3
要するに:
find dirA -type f -size +300m -printf "mv %p dirB/%P\n" | sh
ただし、開始する前に dirB 内のすべてのサブディレクトリが存在している必要があります。このため、次の 2 つの手順を実行することをお勧めします。
cd dirA
find . -type f -size +300m -printf "mkdir -p ../dirB/%h\nmv %p ../dirB/%P\n" | sh
cpio に関して (実際にはサブディレクトリの問題を解決します):
(cd dirA; find . -type f -size +300m) | cpio -p -md dirB
(あなたが言及している同じスレッドのcp(1)に関しては、それはあなたにとって良くありません。なぜなら、それはコピーするからです。 全て ファイル そして dirBの下にdirAというサブディレクトリを作成します。フラグ-Tこの問題を解決できます)
答え4
これで十分でしょう。
find /path -type f -size +300m | while read A ; do DEST=${A/dirA/dirB} ; echo mkdir -p $(dirname $DEST) 2>/dev/null; echo mv $A $DEST ; done
まずそのまま実行して健全性をチェックし、提案されたコマンドに問題がなければ、要素なしで再実行しますecho
。
ファイル構造の例では、次のコマンドが生成されます
mkdir -p ./dirB
mv ./dirA/file1 ./dirB/file1
mkdir -p ./dirB/x
mv ./dirA/x/file2 ./dirB/x/file2
mkdir -p ./dirB/y
mv ./dirA/y/file3 ./dirB/y/file3