重複したファイル名で複雑なフォルダ構造を平坦化

重複したファイル名で複雑なフォルダ構造を平坦化

フォルダ構造が複雑なフォルダがあります。

├── folder1
│   ├── 0001.jpg
│   └── 0002.jpg
├── folder2
│   ├── 0001.jpg
│   └── 0002.jpg
├── folder3
│    └── folder4
│         ├── 0001.jpg
│         └── 0002.jpg
└── folder5
     └── folder6
           └── folder7
                ├── 0001.jpg
                └── 0002.jpg   

すべてのファイルがフォルダ1_0001.jpg、フォルダ1_0002.jpg...folder5_folder6_folder7_0001.jpgなどの一意の名前を持つ親ディレクトリにあるように、フォルダ構造を平坦化したいと思います。

で提案したコードを試してみました。「フラットフォルダ構造」

$ find */ -type f -exec bash -c 'file=${1#./}; echo mv "$file" "${file//\//_}"' _ '{}' \;

echo動作していることを示します。

mv folder3/folder4/000098.jpg folder3_folder4_000098.jpg

ただし、出力ファイルは親ディレクトリに保存されません。ドライブ全体を検索しましたが、出力ファイルが見つかりませんでした。

私も試しました「Bashのファイル名でフラットフォルダ構造」

$ find . -type f -name "*.jpg" | sed 'h;y/\//_/;H;g;s/\n/ /g;s/^/cp -v /' | sh

-v動作していることを示します。

‘./folder3/folder4/000098.jpg’ -> ‘._folder3_folder4_000098.jpg’

しかし、出力の結果、親ディレクトリに隠しファイルが作成され、ワー​​クフローが複雑になりました。以下を使用して、親ディレクトリにこれらの隠しファイルを表示できます。ls -a

私も以下に提案されたコードを試しました「重複ファイルの名前を変更するには、Flatten Folders コマンドを使用します。」

find . -mindepth 2 -type f | xargs mv --backup=numbered -t . && find . -type d -empty -delete

ただし、このコマンドは同様のファイル名を持つファイルを上書きします。

同じ名前のファイルを上書きせずに複雑なフォルダ構造を平坦化する方法に関する提案はありますか?現在の解決策は、1レベルの深さのフォルダ構造でのみ機能するようです。

私の究極の目標は、次のように識別名を連続した数字に変換することです。「フォルダのファイル名を連続した番号に変更」

 a=1
  for i in *.jpg; do
  new=$(printf "%04d.jpg" "$a") #04 pad to length of 4
  mv -- "$i" "$new"
  let a=a+1
 done

ベストアンサー1

あなたの質問に対する最初の解決策がなぜ機能しないのかわかりません。私はあなたがそれを削除することを忘れたと仮定することができますecho。それでも実行していると仮定すると、必要なタスクを実行する必要がある別の方法がありますbash

shopt -s globstar
for i in **/*jpg; do mv "$i" "${i//\//_}"; done

説明する

  • 必要な数のディレクトリまたはファイルを繰り返し一致させるshopt -s globstarbashのglobstar機能をオンにします。**
  • for i in **/*jpg;名前で終わるすべてのファイル(またはディレクトリ)を繰り返し、.jpg各ファイルを$i
  • "${i//\//_}"/のすべてのインスタンスを含む現在のファイル(またはディレクトリ)の名前_

名前が終わるディレクトリがあり、.jpgこれをスキップするには、代わりに次のようにします。

shopt -s globstar
for i in **/*jpg; do [ -f "$i" ] && echo mv "$i" "${i//\//_}"; done

拡張子に関係なく、すべてのファイルについて:

shopt -s globstar
for i in **/*; do [ -f "$i" ] && echo mv "$i" "${i//\//_}"; done

おすすめ記事