70

時々使用しているときxargsは、置換文字列を明示的に使用する必要はありません:

find . -name "*.txt" | xargs rm -rf

他の場合では、次のようなことを行うために置換文字列を指定したいと思います:

find . -name "*.txt" | xargs -I '{}' mv '{}' /foo/'{}'.bar

前のコマンドは、現在のディレクトリの下にあるすべてのテキスト ファイルを に移動し、すべてのファイル/fooに拡張子barを追加します。

置換文字列にテキストを追加する代わりに、ファイルの名前と拡張子の間にテキストを挿入できるようにその文字列を変更したい場合は、どうすればよいでしょうか? たとえば、前の例と同じことをしたいが、ファイルの名前を変更/移動する必要があると<name>.txt/foo/<name>.bar.txtます/foo/<name>.txt.bar

更新:解決策を見つけることができました:

find . -name "*.txt" | xargs -I{} \
    sh -c 'base=$(basename $1) ; name=${base%.*} ; ext=${base##*.} ; \
           mv "$1" "foo/${name}.bar.${ext}"' -- {}

しかし、より短い/より良い解決策があるのではないかと思います。

4

8 に答える 8

32

一時変数の割り当てを使用せずに、これを 1 回のパス (GNU でテスト済み) で行うことができます。

find . -name "*.txt" | xargs -I{} sh -c 'mv "$1" "foo/$(basename ${1%.*}).new.${1##*.}"' -- {}
于 2016-03-09T21:40:50.893 に答える
20

このような場合、whileループの方が読みやすくなります。

find . -name "*.txt" | while IFS= read -r pathname; do
    base=$(basename "$pathname"); name=${base%.*}; ext=${base##*.}
    mv "$pathname" "foo/${name}.bar.${ext}"
done

異なるサブディレクトリに同じ名前のファイルが見つかる場合があることに注意してください。によって重複が上書きされても大丈夫ですmvか?

于 2012-05-29T19:48:31.713 に答える
12

GNU Parallel http://www.gnu.org/software/parallel/がインストールされている場合は、次のことができます。

find . -name "*.txt" | parallel 'ext={/} ; mv -- {} foo/{/.}.bar."${ext##*.}"'

詳細については、GNU Parallel の紹介ビデオをご覧ください: https://www.youtube.com/playlist?list=PL284C9FF2488BC6D1

于 2012-05-30T19:48:32.287 に答える
2

bash/sh 以外のものを使用することが許可されていて、これがただの "mv" のためだけのものである場合は、由緒ある "rename.pl" スクリプトを試すことができます。Linux ではこれを、Windows では cygwin を常に使用しています。

http://people.sc.fsu.edu/~jburkardt/pl_src/rename/rename.html

rename.pl 's/^(.*?)\.(.*)$/\1-new_stuff_here.\2/' list_of_files_or_glob

rename.pl に「-p」パラメータを使用して、実際に実行せずに何を実行するかを指定することもできます。

c:/bin (cygwin/windows 環境) で次のことを試しました。「-p」を使用したので、それが何をしたかを吐き出しました。この例では、ベースとエクステンションを分割し、その間に文字列を追加しています。

perl c:/bin/rename.pl -p 's/^(.*?)\.(.*)$/\1-new_stuff_here.\2/' *.bat

rename "here.bat" => "here-new_stuff_here.bat"
rename "htmldecode.bat" => "htmldecode-new_stuff_here.bat"
rename "htmlencode.bat" => "htmlencode-new_stuff_here.bat"
rename "sdiff.bat" => "sdiff-new_stuff_here.bat"
rename "widvars.bat" => "widvars-new_stuff_here.bat"
于 2012-05-29T18:31:15.710 に答える
1

さらに、ウィキペディアの記事は驚くほど有益です

例えば:

シェルトリック

同様の効果を達成する別の方法は、起動されたコマンドとしてシェルを使用し、そのシェルの複雑さに対処することです。次に例を示します。

$ mkdir ~/backups
$ find /path -type f -name '*~' -print0 | xargs -0 bash -c 'for filename; do cp -a "$filename" ~/backups; done' bash
于 2018-07-23T16:50:52.217 に答える