web-dev-qa-db-ja.com

ファイル名のリストで文字列を見つけて置き換えます

私はそのようなファイルをいくつか持っています(Mac OS Xの場合):

product-103-footer.tpl
product-103-header.tpl
product-103.tpl

すべてのファイル名の「103」を、grepとsedを使用した別のもの、またはそのようなものに置き換えたいと思います。

どうすればいいのですか?

これが私が達成したいことのいくつかの疑似コマンドラインです

find . /[103] | grep 103 | sed s/103/104/

これが理にかなっていることを願っています!

編集:

近くなってる:

find . -name 'product-103*' -print | sed 's/103/104/g'
2

findexecオプションを使用して、すべてのファイルを(再帰的に)ループしてから、単純な文字列置換を使用できます。

find . -type f -name "product-103*" \
-exec sh -c 'echo mv "$0" "${0/103/104}"' '{}' \;

echoを削除して、これで目的の動作が確実に行われるようにします。

基本的に、execが行うことは、{}に引数として渡される、sh -cで見つかったすべてのファイルのファイル名を置き換えることです。この引数は$0として使用できるため、ファイル名になります。この$0引数をmv呼び出しで使用します。ここで、2番目の引数は新しいファイル名です。ここでは、103が104に置き換えられています。ファイル名の空白を正しく処理するには、二重引用符が必要であることに注意してください。

Bashスクリプティングガイドの 文字列操作 を参照してください。


Zshのzmv(OSXから/bin/zshまで)の場合:

autoload -U zmv
zmv -Wn '*103*' '*104*'

-nオプションが必要な場合は、削除してください。

9
slhck

これにはPerlの方が適しています。

find . -name 'product-103*' | Perl -nle '($new=$_) =~ s/103/104/;rename $_,$new'

次のコード

Perl -nle '($new=$_) =~ s/103/104/;rename $_,$new'

最終的にに拡張されます

while (<>) {
    chomp;
    ($new=$_) =~ s/103/104/;
    rename $_, $new;
}

<>演算子は、末尾に「\ n」が付いた各ファイル名を取得し、それを$ _に保存します。その後、chompは「\ n」を切り取ります。次に、変数$new$_から古いファイル名を取得し、103を104に置き換えます。最後に、renameは問題のファイルの名前を新しい名前に変更するだけです。 -n -l -eスイッチの詳細については、perldocの perlrun の部分を参照してください。

2
ltux
for f in product-103*; do mv "$f" "${f/103/104}"; done
2
Lri