SEDで再帰的に交換

SEDで再帰的に交換

このように、複数のディレクトリの例をgrepとsedに再帰的に置き換えることは可能ですか?

grep -e "http://localhost:4000" -r ~/dev_web/_site  | sed -e 's/http:\/\/localhost:4000/https:\/\/another_site.com/g'

これを行うと端末に完了したと表示されますが、再度grepすると次のようになります。

grep -e "https://another_site.com" -r ~/dev_web/_site

4つのファイルだけが変更されたと思います。

私がこうすれば:

 grep -e "http://localhost:4000" -r ~/dev_web/_site/

はいhttp:localhost:4000はまだここにあります。

答え1

パイプラインがファイルを変更していません。正規表現に一致する行を抽出し、そのgrepデータを変更しますが、ファイルを変更しようとしません。

代わりにGNUを想定すると、次のようになりますsed

find ~/dev_web/_site -type f \
    -exec grep -qF 'http://localhost:4000' {} ';' \
    -exec sed -i 's#http://localhost:4000#https://another.site#g' {} +

これにより、ディレクトリ内または下のすべての一般ファイルが検索されます~/dev_web/_site。これらのファイルごとに、grepまずファイルに指定された文字列が含まれていることをテストします。含まれている場合は、sed内部置換のためにGNUが呼び出されます。

このgrepステップは省略できますが、GNUはsed修正タイムスタンプを更新します。みんなこれに関する文書はありません。

以下のディレクトリにあるファイルのサブセットのみを表示したい場合があります~/dev_web/_site。その場合は、-name '*.js'次の項目(または一致させたい名前パターン)に検索を制限してください-type f

-print-exec sed ...印刷を提供する前に追加してください。findsed

関連:

答え2

sedセッションは実際のファイルではなくgrepの出力用です。

ファイルの一覧表示に使用されますgrep(*)

grep -e "http://localhost:4000" -r ~/dev_web/_site -l 

その後、その場で使用しxargsて編集してください。sed -i

xargs sed -i -e 's;http://localhost:4000;https://another_site.com;g'

(btw sedで区切り文字を変更できます)

今みんな一緒にいます。

grep -e "http://localhost:4000" -r ~/dev_web/_site -l |
xargs sed -i -e 's;http://localhost:4000;https://another_site.com;g'

もちろん、1行にすることもできますが、パイプ記号(|)を使用して行を続行することもできます。

(*) ファイル名にスペース、改行、その他の興味深い文字がないとします。

答え3

最初のgrepは代わりにファイルから行を抽出します。リスト文書。
一致するファイルのリストを取得するには、-lgrep オプションを使用します。

$ grep -rl "htt...."  ~/dir

sed を使用してファイルの変更を実行するには、リストを sed に提供します (順序の反対)。

$ sed -e 's#http://localhost:4000#https://another_site.com#g' \
$(grep -rle "http://localhost:4000" ~/dev_web/_site)

空白や新しい行がない「クリーン」ファイル名を想定します。

より強力なオプションは find を使うことです。

fromname='http://localhost:4000
toname='https://another_site.com'
searchdir=~/dev_web/_site
find "$searchdir" -type f \
    -exec grep -qF "$fromname" {} ';' \
    -exec sed -i 's#'"$fromname"'#'"$toname"'#g' {} +

答え4

私にとって最善のことは、次の目的に使用することです。

for i in $(grep -R "string_to_change" | awk -F: '{print $1}');do sed -i 's/string_to_change/string_changed/g' $i ;done

説明: grep -R を使用して文字列を繰り返し検索します。常に名前の前に次を付けてファイルパスを取得できます。最後に抽出されたファイルに対してsed操作を実行します。

挨拶

関連情報