テキストファイルの同じ行にある複数のパターンを一致させ、その行を次の行にコピーして文字列を変更します。

テキストファイルの同じ行にある複数のパターンを一致させ、その行を次の行にコピーして文字列を変更します。

同じ行にあるテキストファイル(別のディレクトリにある)の複数のパターンを一致させ、一致する行を次の行にコピーし、コピーした行を変更したいと思います。 「businessServices」または「BusinessServices」文字列を含むすべての行をコピーしたいです。一致させるパターンが行のどこに表示されるかは関係ありません。ファイルをその場で編集したいです。追加する必要がある行は、次のグローバル置換です。

s#businessServices#userServices#g and s#validate#test#g
s#BusinessServices#UserServices#g
s#BUSINESS_SERVICES#USER_SERVICES#g

ファイル1:

name="businessServices" value="validate"

必須書類1:

name="businessServices" value="validate"
name="userServices" value="test"

ファイル2:

public static final String BUSINESS_SERVICES = "businessServices";

必須書類2:

public static final String BUSINESS_SERVICES = "businessServices";
public static final String USER_SERVICES = "userServices";

ファイル3:

import com.my.ClientBusinessServicesRequest;
import com.my.ClientBusinessServicesResponse;

ClientBusinessServicesRequest clientBusinessServicesRequest = new ClientBusinessServicesRequest();
ClientBusinessServicesResponse clientBusinessServicesResponse = new ClientBusinessServicesResponse();

必須書類3:

import com.my.ClientBusinessServicesRequest;
import com.my.ClientBusinessServicesResponse;
import com.my.ClientUserServicesRequest;
import com.my.ClientUserServicesResponse;

ClientBusinessServicesRequest clientBusinessServicesRequest = new ClientBusinessServicesRequest();
ClientBusinessServicesResponse clientBusinessServicesResponse = new ClientBusinessServicesResponse();
ClientUserServicesRequest clientUserServicesRequest = new ClientUserServicesRequest();
ClientUserServicesResponse clientUserServicesResponse = new ClientUserServicesResponse();

file3は実際には望んでいません(file3が望むことを達成するのが難しい場合)。

import com.my.ClientBusinessServicesRequest;
import com.my.ClientUserServicesRequest;
import com.my.ClientBusinessServicesResponse;
import com.my.ClientUserServicesResponse;

ClientBusinessServicesRequest clientBusinessServicesRequest = new ClientBusinessServicesRequest();
ClientUserServicesRequest clientUserServicesRequest = new ClientUserServicesRequest();
ClientBusinessServicesResponse clientBusinessServicesResponse = new ClientBusinessServicesResponse();
ClientUserServicesResponse clientUserServicesResponse = new ClientUserServicesResponse();

私は次の方法を試しましたが、それぞれ希望の結果のいくつかを得ましたが、すべてではありません。

grep -rl businessServices . | xargs sed -i 's#\(.*\)validate\(.*\)#&\n\1test\2#' 

grep -rl businessServices . | xargs sed -i 's#\(.*\)businessServices\(.*\)#&\n\1userServices\2#'

grep -rl BusinessServices . | xargs sed -i 's#\(.*\)BusinessServices\(.*\)#&\n\1UserServices\2#g'

grep -rli businessServices . | xargs sed -i 's#\(.*\)BUSINESS_SERVICES\(.*\)#&\n\1USER_SERVICES\2#' 

答え1

自動印刷(-n)および内部編集(-i)なしで拡張正規表現モード(-E)でGNU sedを使用します。

sed -Eni '
  /[bB]usinessServices|BUSINESS_SERVICES/{
    h
    :loop
      ${g;bend;}
      n
    //{H;bloop;}
    x
    :end
    p'"
    $(< cmds.sed)
    "'
    $!G
  }
  p
' file3

  • OR正規表現を使用して必要な行を選択してください。
  • その後、ループを開始して、所望の連続行を保留状態に保存する。
  • 保留状態に保存された一連の連続ラインを印刷します。
  • 次に、ファイル(cmds.sed)に保存されているsedコマンドを挿入して交換を実行します。
  • 変更されたファイル+保持された内容を印刷します。

cmds.sedファイルの内容:

$ cat cmds.sed

s#businessServices#userServices#g

s#validate#test#g

s#BusinessServices#UserServices#g

s#BUSINESS_SERVICES#USER_SERVICES#g

答え2

GNU awkで「内部」編集を実行するには、空のENDFILE行またはファイルの終わりが表示されるまで変更された行をバッファリングしてから印刷します。

$ awk -i inplace '
    !NF {
        printf "%s", buf
        buf = ""
    }
    {
        print
        orig = $0
        gsub(/businessServices/,"userServices")
        gsub(/validate/,"test")
        gsub(/BusinessServices/,"UserServices")
        gsub(/BUSINESS_SERVICES/,"USER_SERVICES")
    }
    $0 != orig {
        buf = buf $0 ORS
    }
    ENDFILE {
        printf "%s", buf
        buf = ""
    }
' file1 file2 file3

$ head file1 file2 file3
==> file1 <==
name="businessServices" value="validate"
name="userServices" value="test"

==> file2 <==
public static final String BUSINESS_SERVICES = "businessServices";
public static final String USER_SERVICES = "userServices";

==> file3 <==
import com.my.ClientBusinessServicesRequest;
import com.my.ClientBusinessServicesResponse;
import com.my.ClientUserServicesRequest;
import com.my.ClientUserServicesResponse;

ClientBusinessServicesRequest clientBusinessServicesRequest = new ClientBusinessServicesRequest();
ClientBusinessServicesResponse clientBusinessServicesResponse = new ClientBusinessServicesResponse();
ClientUserServicesRequest clientUserServicesRequest = new ClientUserServicesRequest();
ClientUserServicesResponse clientUserServicesResponse = new ClientUserServicesResponse();

答え3

私はこれが両方のあなたの要件を満たしていると思いますsed

$ sed -e 's/.*business.*\|.*Business.*/&\n&/' \
    -e 's/business/user/g2' \
    -e 's/BUSINESS/USER/2' \
    -e '/^import com.my.ClientBusinessServicesResponse/s/Business/User/2' \
    -e '/^ClientBusinessServicesResponse/s/Business/User/4g' file1 file2 file3

# file1
name="businessServices" value="validate"
name="userServices" value="validate"

# file2
public static final String BUSINESS_SERVICES = "businessServices";
public static final String USER_SERVICES = "userServices";

# file3
import com.my.ClientBusinessServicesResponse;
import com.my.ClientUserServicesResponse;

ClientBusinessServicesResponse clientBusinessServicesResponse = new ClientBusinessServicesResponse();
ClientUserServicesResponse clientUserServicesResponse = new ClientUserServicesResponse();

ついに

$ sed '/userServices/s/validate/test/' file1

関連情報