5

jpg.jpgで終わるいくつかのファイル名を(bashで)のみで終わるように変更したいと仮定し、 to.jpgの出力をパイプすることでそれを行いたいとします:findxargs

を使用してsed

find . -iname '*jpg.jpg' | xargs -I % mv -iv % $(echo % | sed 's/jpg.jpg/.jpg/g')

ただし、これはの宛先ファイルでは に置き換えjpg.jpgられません。.jpgmv

を使用してawk

find . -iname '*jpg.jpg' | xargs -I % mv -iv % $(echo % | awk '{gsub(/jpg.jpg/,".jpg")}; 1')

これはどちらも置き換えません。私は何かを逃しましたか?

4

5 に答える 5

5

これを行うには、ファイル名を取得して名前を変更するスクリプトを記述します。

#!/bin/sh

for FILE
do
    mv $FILE `basename $FILE jpg.jpg`.jpg
done

そのスクリプトは、を介して簡単に呼び出すことができxargsます。

それを単一のコマンドラインに粉砕したい場合はそれを行うことができますが、通常は問題を起こす価値はありません。

編集:1つのコマンドラインでそれを行う必要がある場合は、おそらく次のことを行わずに別のトリックをxargs使用sedします:の出力をfindシェルスクリプトに変換するために使用します:

find . -iname '*jpg.jpg' | sed -e 's/\(.*\)jpg\.jpg$/mv & \1.jpg/' | sh

より少ない子供をフォークできるという利点は、とにかく繰り返しxargs走る必要があることによって打ち負かされます。そのmv利点が本当に必要な場合は、私の最初のオプションのようなソリューションが必要ですが、フォークオフせずに複数の呼び出しを実行できるようなものでコーディングされています。perlrename()mv

于 2012-10-31T22:00:47.373 に答える
4

システムでコマンドを使用できる場合はrename、次のコマンドが機能するはずです。

rename 's/(.*)jpg.jpg/$1.jpg/g' *jpg.jpg
于 2012-10-31T21:39:48.687 に答える
3

$(...)xargs を実行する前に bash によって評価されるため、xargs は現在 mv の 2 番目の引数としてそのままの式の出力を参照します。

したがって、次と同等です。

... | xargs -I % mv % %
于 2012-10-31T21:40:10.507 に答える
2

これにはGNUパラレルを使用します。

find . -iname '*jpg.jpg' | parallel mv {} {.}

{}は入力に{.}置き換えられ、入力から最後の拡張子を引いたものに置き換えられます。--dry-runparallel を使用して、何が行われるかを確認します。

編集 - file1jpg.jpg を処理する必要があります

大文字と小文字の区別に関するニーズに応じて、これはパラメーター展開または GNU sed を使用して実行できます。

パラメータ拡張:

find . -iname '*jpg.jpg' | parallel v={}\; mv '{}' '${v/jpg.jpg/.jpg}'    

GNU sed の場合:

find . -iname '*jpg.jpg' | parallel mv '{}' '$(echo {} | sed -r "s/jpg\\.(jpg)$/.\1/I")'
于 2012-10-31T22:33:48.400 に答える
1

xargsまたはの必要はありませんfind

for i in *jpg.jpg; do mv "$i" "$(echo $i | sed 's/jpg.jpg$/.jpg/')"; done

そして、次のいずれかsedを実際に必要とすることはありません。awk

for i in $(find . -type f -name "*jpg.jpg"); do mv "$i" "${i/%jpg.jpg/.jpg}"; done

別の方法は次のとおりです。

find . -type f -name "*jpg.jpg" -exec bash -c 'mv $0 ${0/%jpg.jpg/.jpg}' {} \;
于 2012-10-31T21:55:30.677 に答える