web-dev-qa-db-ja.com

grepによって検出されたすべてのファイルの文字列を置き換えます。それを動作させることができません

Grepで必要なファイルをすべて見つけました:grep --include=\*.{php,ini,conf,sh} -ril -P "'([\d\w\-\_\.]+)(@domain.com)'" '/var/www_data/somepath/'

今では、置換プロセスにsedまたはPerlを使用していると思いますが、残念ながら、どちらでも上記の正規表現を使用する方法がわかりません。 この方法この方法 を見ましたが、私が言ったように、私はそれを私のパターンで動作させることができませんでした(つまり、次の行で>を取得することを意味しますコマンドを実行した後。sedまたはPerlで使用した場合、上記の正規表現に問題があると思います)。そのため、この問題に関するアドバイスはありがたいです。

また、それが可能かどうかはわかりませんが(それほど重要ではありません)、File fixed: /path/to/file/(grepリストから取得したファイル名など)など、置換が発生したファイルごとに文字列を出力したいと思います。

4
Igor Yavych

通常、ヒットした後、次の行に>が表示される場合は、引用符の1つがまだ閉じられていないことを意味します。私はあなたの正規表現でその間違いを見つけることができませんでした。ただし、パス/var/www_data/somepath/を一重引用符で囲む必要はありません。 somepathには変わった文字はないと思いますか?

とにかく、私はあなたの正規表現をsedでテストしました。 \d\wは私にとってはvim構文のように見えます。そのため、ASCIIに変換しました(常に機能します)。また、[]の内部では、.をエスケープする必要はありません。

sed -r "s/'([A-Za-z0-9_-.]+)(@domain.com)'/'adsf'/g" test.dat

実際、タスクにはsedまたはPerlを使用できます。 GBのデータがない限り、ファイルリストを生成するために必ずしもgrepは必要ありません。次に、事前に並べ替えると、速度が向上する可能性があります。

regexをテストするには、次のようにします。

cd /var/www_data/somepath/
sed -r 's|pattern|replace-pattern|g' a_single_file.php

結果に満足したら、-ibak--in-place=bak)引数を追加して、すべてのファイルで実行します。

find . -type f -name '*.php' -o -name '*.ini' -o name '*.conf' -o -name '*.sh' \
-exec sed -r -ibak 's|pattern|replace-pattern|g' '{}' \; 

元のファイルは<orignalname.php>.bakに入れられています。

あなたの最後の質問に答えるために。このジョブの場合、grepは必要なツールであり、上記のsedによって生成された.bakファイルで実行できます。

grep --recursive --include='*.bak' -E --files-with-matches 'pattern' . > files_fixed.txt

または、単に:

find . -type f -name '*.bak'
2
Sebastian

GNU sedを使用すると、sed -iを使用できます。

sed -i 'script' *.{php,ini,conf,sh}
2
mikeserv

ほとんどのLinux:

sed -i 's#FIND#REPLACE#g' *.{php,ini,conf,sh}

MacOSの場合:

sed -i '' 's#FIND#REPLACE#g' *.{php,ini,conf,sh}

MacOSのsedは、-iの後にバックアップパラメータを想定しています。バックアップファイルが必要ない場合は、空の文字列を使用してください。 「g」はグローバル置換用です。それ以外の場合は、行ごとの最初の行にすぎません。

1
user83305