5

私はいくつかの作業コードを持っています。それは非常に簡単です。すべての *.jpg ファイルをコピーし、*1.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
4

2 に答える 2

6

ディレクトリ構造に対して再帰的に何かを行うコマンドは次のfindとおりです。

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

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

そのようなファイル名がある場合、またはその可能性がある場合は、 を使用して null 文字 (ファイル名では許可されていません) で区切られた各ファイル名を出力し-print0、 を使用while read -d $'\0' iして null で区切られた結果をループします。

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

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

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

目で見て結果が良さそうに見えたら、 を削除しechoて再度実行し、実際に実行します。

于 2012-11-05T03:22:30.583 に答える
2

Bash 4 を使用している場合はglobstar、再帰的なファイル名展開を有効にするために使用できます (つまり、サブディレクトリ内のファイルにも一致します)。

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

cpp/s:ファイル名などにスペースが含まれている場合に備えて、引数を引用符で囲みました。

于 2012-11-05T05:34:24.847 に答える