ファイル名に基づいてサブディレクトリに格納されているファイルでいっぱいのディレクトリがあります。
20d1/d325/52d1/20d1d32552d1a95249e62662fbdf924dd72c4027.jpg
ccaf/13cf/3199/ccaf13cf319930e80f5f2ad02525b93e1326c160.jpg
ec07/53bd/2355/ec0753bd2355fa8ec5cf5163e219c162cce3b03a.jpg
...
ご覧のとおり、ファイル名の最初の12文字は3つのレベルのサブディレクトリを作成するために使用されます。残念ながら、各ディレクトリ名に4文字が選択され、ファイル数がファイルシステムのディレクトリあたりのエントリ数である32,000のディレクトリ制限を超えました。したがって、次のように書き直す必要があります。
20d/1d3/255/2d1/20d1d32552d1a95249e62662fbdf924dd72c4027.jpg
cca/f13/cf3/199/ccaf13cf319930e80f5f2ad02525b93e1326c160.jpg
ec0/753/bd2/355/ec0753bd2355fa8ec5cf5163e219c162cce3b03a.jpg
...
したがって、ディレクトリごとに4つではなく3つの文字が使用されます。ファイルが多いため、プロセスはできるだけ早くする必要があります。
私は次のことを試しましたfind
。
find /path/to/files -mindepth 4 -type f -regextype posix-extended -regex \
".*/([0-9a-f]{4}/){3}(([0-9a-f]{3})([0-9a-f]{3})([0-9a-f]{3})([0-9a-f]{3})[0-9a-f]+\.\w+)"
これにより、すべてのファイルが正しく印刷されますが、書き換えを進める方法がわかりません。書き換えプロセス中に正規表現キャプチャグループを使用してパス$3/$4/$5/$6/$2
(find
正規表現の逆参照)を再構築したいと思います。しかし、find
このようなものはサポートされていないようです。
find ... -exec cp {} /elsewhere/$3/$4/$5/$6/$2 ;
この問題を処理する最良の方法は何ですか?そして(私はこれについて経験がありません)sed
のいくつかの組み合わせですか?タスクを実行するxargs
代わりに繰り返す必要がありますか?find
少し迷子になった。
ベストアンサー1
ファイルをコピーするには、findとGNU tarの組み合わせを使用して操作を実行できます。
$ find -type f ... -print0 \
| tar -c -f - --null --files-from - \
| tar -C DEST_BASE -v -x -f - \
--show-transformed \
--transform 's,PATTERN,REPLACE,OPTIONS
(findはすべてのソースファイル名を生成し、最初のtarはそれをパイプに読み込み、2番目のtarはファイル名/パス変換を実行します)
デフォルトでは、この--transform
オプションにはデフォルトの正規表現が必要ですが、x
regexp-optionを使用することもできます。別の有用な正規表現オプションは、大文字とi
小文字を区別しない一致です。