別のフォルダにある同じ名前のファイルを1つのフォルダに移動する

別のフォルダにある同じ名前のファイルを1つのフォルダに移動する

参加者を表す複数のフォルダがあります。各フォルダにcon_0001.img。このすべてのファイルを移動したいです(con_0001.img)を新しいフォルダにコピーします(個々の参加者フォルダに配置する代わりに)。

以下のコードは次のように見えます。con_0001.imgという名前の新しいフォルダに移動します。SA_A:

find . -name "con_0001.img" -exec mv '{}' "./SA_A/" ";"

ただし、すべてのファイルの名前があるため、con_0001.img新しいフォルダには1つのファイルしか残りません(おそらくそれ以降のすべてのファイルが互いに上書きされるため)。

私はこのオーバーライドを防ぐための提案を見つけました。つまり:

find . -name "con_0001.img" -exec mv --backup=numbered "{}" "./SA_A/" \;

しかし、最終的にファイルができました。con_0001.img複数のフォルダから消えて上書きされたようです。mvに変更すると、cpファイルも作成されます(ただし、ファイルをコピーして期待どおりにファイルはそのまま残ります)。

上書きを防ぐ方法はありますか?もちろん、ファイルを新しいフォルダに移動するときに親ディレクトリ名(参加者番号)の一部をファイルに追加する方法はありますか?たとえば、

p102/con_0001.img ----> p102_con_0001.img

p105/con_0001.img ----> p105_con_0001.img

移動したファイルに親ディレクトリを追加する必要があるように、次のコードを適用してみました。

find . -name 'con_0001.img' | while read filePath; do cp "$filePath" './SA_A'/"$(echo "$filePath")"; done

ただし、エラーが返されます。

一般ファイル '/SA_A/./p105/con_0001.img' を生成できません。そのファイルやディレクトリはありません。

新しいフォルダ以降に予期しない期間があるようです。/SA_A/。これがコードが機能しない理由ですか?この期間はどこから来ましたか?

ベストアンサー1

mkdir SA_A
find . -name "con_0001.img" -exec sh -c '
    for f; do d=${f%/*}; mv -- "$f" "./SA_A/${d#./}${f##*/}"; done
' findsh {} +

forループは見つかった各ファイルを繰り返します。

  • d=${f%/*}ファイルのデフォルト名である一番右の/*部分を削除します。f
  • ${d#./}./ファイルの先頭部分を削除します。
  • ${f##*/}ファイルのデフォルト名を取得し、最後のファイルを削除します/

実行前:

$ ls a1 a2 a3
a1:
con_0001.img

a2:
con_0001.img

a3:
con_0001.img

実行後:

$ ls a1 a2 a3 SA_A/
a1:

a2:

a3:

SA_A/:
a1con_0001.img  a2con_0001.img  a3con_0001.img

しかし、単一のシェルループを使用すると、はるかに簡単です。

for f in */con_0001.img; do
    mv -- "$f" "./SA_A/${f%/*}_${f#*/}"
done

おすすめ記事