2017-11-04 21 views
0

私はsedを使ってすべてのファイルの文字列を置き換えます。シェル変数でSed置換が機能しない

私はこれを持っているが、それは仕事doens't:

#!/bin/bash 
OLD="oldtext" 
NEW="newtext" 

grep -rli '$OLD' * | xargs [email protected] sed -i 's/$OLD/$NEW/g' @ 

しかし、この

grep -rli 'oldtext' * | xargs [email protected] sed -i 's/oldtext/newtext/g' @ 

作品を!コマンドを修正するにはどうすればよいですか?

+2

変数は一重引用符では展開されません。二重引用符を使用し、 'oldtext'や' newtext'の代わりに正規表現メタ文字のいくつかを使用しないよう注意してください。 – randomir

+0

ヒント:[shellcheck](http://shellcheck.net)がこれと他の一般的な問題を自動的に検出します –

答えて

0

としてはrandomirさんのコメントで指摘し、彼はにリンク質問、あなたは変数が展開されるように、二重引用符を使用する必要があります。

old="oldtext" 
new="newtext" 
grep -rZli "$old" | xargs -0 sed -i "s/$old/$new/gi" 

は、私もいくつか他のものを変更:

  • を環境変数に予約されている名前との衝突を避けるための小文字の変数名
  • grep -Zファイル名に改行などの特殊文字を扱うためにNULバイトでファイル名を区切るオプション
  • ファイル名がの終わりに行くと、とにかく作業ディレクトリがデフォルト
  • -0はNULバイト分離ファイル名
  • を期待するxargsのためのオプションは(非推奨)-iオプションをスキップとして、sedのパターンの後*をスキップコマンドはとにかく置換の
  • iフラグは、grepコマンド

これらのいくつかは、GNUのgrepの、xargsのを必要とし、sedのでは大文字小文字を区別しないマッチングを一致させます。

あなたが最初にそれらをgrepを正当化するために、ファイルの膨大な数を見ていない場合は、あなただけの一般**/*グロブを使用して、それらすべての上に単一のsedのプロセスを実行することができます。

shopt -s globstar 
sed -i "s/$old/$new/gi" **/* 

これは文句を言うでしょうディレクトリについて実行しようとしているsedについてですが、傷つけません。すべてのファイルに.txtのような共通の拡張子がある場合は、それを避けるために**/*.txtを使用できます。一方で、あなたはファイルのトンを持っていて、タスクを加速したい、場合

、あなたは並列化するxargsはの-Pオプションを使用することができます:4の並列処理のための

grep -rZli "$old" | xargs -0 -P 4 sed -i "s/$old/$new/gi" 

を。

+0

こんにちは、ありがとうございます!私はこのgrep -rZli "$ old"を使います。 xargs -0 -P 4 sed -i "/ $ old/$ new/gi"とエラーsedがあります:-e式#1、char 10: 's 'に不明なオプションがありますか? –

+0

@ J.Dawtonあなたの 'old'または' new'変数にスラッシュが含まれている場合に起こります。 '' s' $ old @ $ new @ "'のように '' s'コマンドのために別のデリミタを選択する必要があります。 '' old''や 'new''以外のものは動作しません。 –

+0

それは動作します! :D非常に非常にTHX! –

関連する問題