bashで一度に複数の部分文字列を置き換えるにはどうすればよいですか?

bashでエコーされる画像ファイルを含むディレクトリがあります。エコーしながら、ファイル名と拡張子の両方を1行のコマンドで置き換えたい。

サンプルファイル:

images/file_name_1.jpg images/file_name_2.jpg 

通常、次のように1回の置換を行うことができます:

 for i in images/*; do echo ${i/file/image}; done  

出力は次のようになります:

 images/image_name_1.jpg images/image_name_2.jpg  

forループを維持し、「jpg」文字列を「png」に置き換えるにはどうすればよいですか?これは単なるインスタンスであり、ドットをコンマなどに置き換えることができます。

これを試すと:

 for i in images/*; do echo ${{i/jpg/png}/file/image}; done  

機能しません。他に解決策やアイデアが見つかりません。これは可能ですか?もしそうなら、どのようにしたらよいですか?

コメント

  • 私は'これがbashで機能しなかった理由がわかりません'しかし、ネストされた置換はzshで期待したとおりに機能します。環境によっては、より良いシェル;)

回答

簡単なアプローチは、結果を変数に割り当ててから作業することです。例:

 for filename in images/* do echo "filename is now $filename" filename=${filename/jpg/png}; echo "filename is now $filename" filename=${filename/file/image}; echo "filename is now $filename" echo "final filename is ${filename}" done  

コメント

  • この回答は完全ではありません。置換はファイル名文字列のどこにでも適用されます。質問に基づいて、Kubilayはプレフィックスと拡張子(サフィックス)を置き換えたいと考えています。これを変更して考慮に入れることができますか。 :$ {var /#Pattern / Replacement} varのプレフィックスがPatternと一致する場合は、ReplacementをPatternに置き換えます。$ {var /%Pattern / Replacement} If varのサフィックスがPatternと一致し、Patternの代わりにReplacementを使用します。
  • @rMistero '回答が受け入れられたという理由だけで、別の回答を投稿することを禁止するルールはありません。実際、特にあなたが提案しているもののセマンティクスが異なるので、あなたはすべきだと思います。とは言うものの、これはOPが試みたと言ったことを実行する方法であるため、他にも有効な結果があったとしても、これはOPが達成したいと思っていたことと一致していると考えて間違いありません。

回答

前の置換を変数に割り当て、代わりにその変数で置換を実行できます

 for i in images/* do j=${i/jpg/png} echo ${j/file/image} done  

コメント

  • わからないそれが機能する場合。 " for i in images / *; do j = {i / jpg / png} echo $ {j / file / image}; done "は" {i / jpg / png} "を繰り返しエコーします。
  • はい:" for i in images/*。jpg; do j = $ {i / jpg / png};エコー$ {j / file / image};完了"。ありがとう!

回答

任意の文字列を変更する

$ echo "images/file_name_1.jpg" | perl -pE "s/file/image/;s/jpg$/png/;" images/image_name_1.png 

名前を変更するためのショートカット(これが最終的な目標になる可能性があります:

$ rename "s/file/image/;s/jpg$/png/;" "$i" 

コメント

  • ファイルごとに1回Perlを呼び出すのはやり過ぎだと思いますが、少なくとも今はこれで質問の答えが得られます。:)
  • @MichaelKj ö rlingファイルごとにPerlを呼び出す必要はありません'。rename … images/*を実行できます。ただし、これにはDebianベースのディストリビューションが必要です(他のLinuxバリアントのrenameは完全に異なるコマンドです)。
  • @Gilles最初のバージョンについてもっと考えていました。特に、ファイルの名前変更について尋ねられた質問には'が何もないためです。この回答の元の(猶予期間が編集された)バージョンには、renameコマンドの提案しかありませんでした。

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です