web-dev-qa-db-ja.com

findを使用して、見つかったすべてのファイルを同じディレクトリ内の新しい名前にコピーするにはどうすればよいですか?

ほぼやりたいことを実行する簡単なコマンドがあります。以下は、サフィックスが「_compressed.swf」のすべてのファイルを検索し、それぞれを「.bak2」が追加された同じディレクトリにコピーします。

'../content' -name '* _compressed.swf' -print0 |を検索します。 xargs -0 -I {} cp {} {}。bak2

結果
In:/content/somefile_compressed.swf
出力:/content/somefile_compressed.swf.bak2

ただし、一貫性を保つために、cpで再帰フラグを使用するのではなく、「_ compressed.swf」を「_content.swf」に置き換える必要があります。

目的
In:/content/somefile_compressed.swf
出力:/content/somefile_content.swf

5

このソリューションはおそらく最も移植性があります。

find "../content" -name "* _compressed.swf" -exec sh -c'cp {} `dirname {}`/`basename {} compressed.swf`content.swf '\; 

Perlで配布されている有名な rename.pl スクリプトと、これを少し簡単にすることができた rename コマンドもあります。これらはすべてのディストリビューションで利用できるわけではありませんが、これらのコマンドはほとんどの場合利用できます。

5
John T

これはすべて1行で処理できると確信しています。私は1行のソリューションに本当に近づき、いくつかの助けを借りてさらに近づきましたが、成功しませんでした。次の作品:

#!/bin/bash

# Read all file names into an array
FilesArray=($(find "../content" -name "*_compressed.swf"))

# Get length of an array
FilesIndex=${#FilesArray[@]}


# Use for loop read all directory names
for (( i=0; i<${FilesIndex}; i++ ));
do
    source="${FilesArray[$i]}"
    destination="$(echo "${source}" | sed 's/compressed/content/')"
    cp "${source}" "${destination}"
done

exit 0;
1

これでうまくいくはずで、本当に必要な場合は1つのライナーに折りたたむことができると思います;)

find ../content -name '*_compressed.swf' | while read file
do
cp "$file" "${file/_compressed.swf/_content.swf}"
done

これらの場合、bashパターンの置換はうまく機能します。

0