2012-11-05 14 views
5

私はいくつかの作業コードを用意しています。非常に簡単です。* .jpgファイルをすべてコピーして* 1.jpgに名前を変更します。Bashは、サブディレクトリを持つディレクトリ内のすべての.jpgファイルに対してスクリプトを実行します。

for i in *.jpg; do cp $i ${i%%.jpg}1.jpg; done 

それはディレクトリ内のすべてのファイル上で動作するようにどのように私は、そのディレクトリのサブディレクトリ内のすべてのファイル

例ディレクトリ構造、これを実行することができます。

test/test1/test2/somefile.jpg 
    test/anotherfile.jpg 
    test/test1/file.jpg 
etc 
+2

'そのディレクトリのサブディレクトリ内のすべてのファイル' =再帰的に – nickhar

答えて

6

コマンドへディレクトリ構造に再帰的に何かをfindです:

find . -name "*.jpg" -exec bash -c 'file="{}"; cp "$file" "${file%%.jpg}1.jpg"' \; 

for i in $(find ...)の代わりに-execを使用すると、スペースを含むファイル名が処理されます。もちろん、まだ1つの引用符があります。ファイル名に"が含まれている場合、file="{}"file="name containing "quote characters""に展開されますが、これは明らかに壊れています(filename containing quoteになり、charactersコマンドを実行しようとします)。

あなたがそのようなファイル名を持っている、またはあなたが、その後、-print0を使用して(ファイル名で許可されていない)、ヌル文字で区切られた各ファイル名をプリントアウトし、ヌル区切りの結果をループにwhile read -d $'\0' iを使用する可能性がある場合:

find . -name "*.jpg" -print0 | \ 
    (while read -d $'\0' i; do cp "$i" "${i%%.jpg}1.jpg"; done) 

このような複雑なコマンドの場合と同様に、何も実行せずにテストして、実行前に賢明に展開していることを確認することをお勧めします。これを行うための最善の方法は、echoと実際のコマンドを付加することで、その代わりにそれを実行するので、あなたはそれが実行されるコマンドが表示されます:あなたはそれをeyeballedてきたとの結果が、よさそうだしたら

find . -name "*.jpg" -print0 | \ 
    (while read -d $'\0' i; do echo cp "$i" "${i%%.jpg}1.jpg"; done) 

echoを削除して再度実行して、実際に実行してください。

+0

find。 -name "* .jpg" -exec bash -c 'file = "{}"; cp "$ file" "$ {file %%。jpg} 1.jpg" '\; は正しいスクリプトです、ありがとう – user1051532

2

あなたはバッシュ4持っている場合は、再帰的なファイル名展開を可能にするためにglobstarを使用することができますが(つまりは、同様にサブディレクトリ内のファイルと一致する)

shopt -s globstar 
for i in **/*.jpg; do cp "$i" "${i%%.jpg}1.jpg"; done 

P/S:私はそこの場合にはcpの引数の前後に引用符を追加しましたファイル名やその他のもののスペースです。

関連する問題