2

ディレクターの構造を変更しました。次のことを行いたいと考えています。

  • 再帰的なgrepを実行して、一致するすべてのインスタンスを見つけます
  • 更新された場所の文字列に変更

1 つの例 (数百のうち) は次のようになります。

from common.utils import debug  --> from etc.common.utils import debug

私が探しているもののすべてのインスタンスを取得するには、次のようにします。

$ grep -r 'common.' ./

commonただし、前にスペースがあることも確認する必要があります。これを見つけて置き換えるにはどうすればよいですか?

4

3 に答える 3

4

リファクタリングの例ではパッケージだけでなくインポートも変更されるため、何が必要かを正確に伝えるのは困難common. -> etc.common.ですが、ディレクトリ内のすべてのファイルに対して次のように変更されます。

sed -i 's/\bcommon\./etc.&/' $(egrep -lr '\bcommon\.' .)

これは、gnu sed が利用可能であることを前提としていますが、これはほとんどの Linux システムで行われています。また、sed が一度に処理するにはファイルが多すぎる場合、これは失敗します。その場合、これを行うことができます:

egrep -lr '\bcommon\.' . | xargs sed -i 's/\bcommon\./etc.&/'

sed -i'.OLD' 's/\bcommon\./etc.&/'元のファイルのバックアップを取得するには、sed コマンド as を実行することをお勧めします。

于 2012-06-03T02:01:49.080 に答える
1

grep実装が Perl 構文 (フラグ、たとえば Linux では通常利用可能) をサポートしている場合、-P単語境界などの追加機能を利用できます。

$ grep -Pr '\bcommon\.'

ところで:

grep -rfindロブの例のように、以前にパイプされたコマンドよりもはるかに遅くなる傾向があります。さらに、見つかったファイル名に空白が含まれていないことが確実な場合は、次を使用するxargs方がはるかに高速です-exec

$ find . -type f -name '*.java' | xargs grep -P '\bcommon\.'

または、Tim の例に適用されます。

$ find . -type f -name '*.java' | xargs sed -i.bak 's/\<common\./etc.common./'

後者の例では、変更された各ファイルの *.bak バックアップを作成した後に置換が行われることに注意してください。このようにして、コマンドの結果を確認してからバックアップを削除できます。

$ find . -type f -name '*.bak' | xargs rm

oopsie を作成した場合は、次のコマンドで以前のバージョンが復元されます。

$ find . -type f -name '*.bak' | while read LINE; do mv -f $LINE `basename $LINE`; done

もちろん、ファイル名とパスに空白がないかどうかわからない場合は、find-execパラメーターを介してコマンドを適用する必要があります。

乾杯!

于 2012-06-03T02:11:01.730 に答える
1

これは、find を使用して大まかに行う方法です。これにはテストが必要です

 find . -name \*.java -exec sed "s/FIND_STR/REPLACE_STR/g" {}

これは、「現在のディレクトリから開始して、.java で終わるすべてのファイルを検索し、そのファイルに対して sed を実行します (ここで、{} は現在見つかったファイルのプレースホルダーです)」「s/FIND_STR/REPLACE_STR/g」は、FIND_STR を REPLACE_STR に置き換えます現在のファイルの各行。

于 2012-06-03T01:56:03.967 に答える