텍스트 파일의 같은 줄에 있는 여러 패턴을 일치시키고 해당 줄을 다음 줄에 복사한 후 문자열을 수정하세요.

텍스트 파일의 같은 줄에 있는 여러 패턴을 일치시키고 해당 줄을 다음 줄에 복사한 후 문자열을 수정하세요.

같은 줄에 있는 텍스트 파일(다른 디렉터리에 있음)의 여러 패턴을 일치시키고 일치하는 줄을 다음 줄에 복사하고 복사된 줄을 수정하고 싶습니다. "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

관련 정보