문자열이 포함된 텍스트 파일에서만 줄을 바꾸려면 sed 또는 ed를 사용하시겠습니까? [폐쇄]

문자열이 포함된 텍스트 파일에서만 줄을 바꾸려면 sed 또는 ed를 사용하시겠습니까? [폐쇄]

일치하는 문자열이 두 줄에 모두 있는 경우에만 줄을 바꿔야 합니다.

앞으로:

REF*CE*-------------------------
REF*1W*-------------------------

뒤쪽에:

REF*1W*-------------------------
REF*CE*-------------------------

나는 이것을 시도했지만 작동하지 않습니다.

ed -s testfile.txt <<<$'/REF*CE*/-0,/REF*CE*/+0m/REF*1W*/\nw\nq'

답변1

sed -e :a -e '$!N;s/^\(REF\*CE.*\)\n\(REF\*1W.*\)/\2\n\1/;ta' -e 'P;D' <testfile.txt 
  1. 마지막 행에 없으면 다음 행을 추가합니다.
  2. 일치하는 항목이 있는 경우에만 현재 줄에서 교체가 수행됩니다 substring containing pattern 1 + newline + substring containing pattern 2. 교체는 두 개의 하위 문자열을 뒤집습니다. 교체 후 반품 라벨: a.
  3. 일치하는 항목이 없으면 패턴 공간을 그대로 인쇄합니다. 그런 다음 패턴 공간을 삭제하고 루프를 다시 시작합니다.

주변 선의 예...

In:

    XEF*CE*------------------------- 
    REF*CE*------------------------- 
    REF*1W*------------------------- 
    REF*2W*------------------------- 

Out:


    XEF*CE*------------------------- 
    REF*1W*------------------------- 
    REF*CE*------------------------- 
    REF*2W*------------------------- 

보다 일반적으로 모든 모드 1 및 모드 2에 적용됩니다.

sed -e :a \
    -e "\$!N; s/^\(.*${pattern1}.*\)\n\(.*${pattern2}.*\)/\2\n\1/;ta" \
    -e 'P;D' < inputfile

답변2

특정 정규식과 일치하는 두 줄(멀리 떨어져 있을 수 있음)을 바꾸는 방법에 대한 일반적인 솔루션은 다음과 같습니다 ed.

  1. 복사한 줄 지나서 두 번째 줄까지.
  2. 이동하다두 번째 행은 원래 첫 번째 행 뒤에 옵니다.
  3. 삭제첫 번째 원본 행입니다.

또는 ed편집 명령을 사용하십시오.

  1. /pat1/t/pat2/
  2. ?pat2?m/pat1/
  3. ?pat1?d

예는 다음과 같습니다문서

CLP*815900102*2*489.8*101.5*82.29*13*PVJLS03YP0000*13*7
AMT*AU*489.8
REF*6R*00000000002
DTM*472*20160528
CAS*OA*23*306.01
CAS*PR*2*82.29
SVC*HC:99212:25*489.8*101.5**1
AMT*B6*411.43

AMT첫 번째 행을 두 번째 행으로 바꾸고 싶습니다 CAS. pat1이고 ^AMT\*AU앞으로도 pat2될 것입니다 ^CAS\*PR. *정규식에서 문자 그대로 처리되도록 이스케이프 처리해야 합니다 .

변경 사항을 더 쉽게 볼 수 있도록 아래에 주석을 달았습니다. XXX각 작업 후 파일의 현재 위치를 나타냅니다 .

  1. /^AMT\*AU/t/^CAS\*PR/생산하다

    CLP*815900102*2*489.8*101.5*82.29*13*PVJLS03YP0000*13*7
    AMT*AU*489.8        <-- Line copied *from* here
    REF*6R*00000000002
    DTM*472*20160528
    CAS*OA*23*306.01
    CAS*PR*2*82.29
    AMT*AU*489.8        <-- Line copied *to* here (XXX)
    SVC*HC:99212:25*489.8*101.5**1
    AMT*B6*411.43
    
  2. ?^CAS\*PR?m/^AMT\*AU/생산하다

    CLP*815900102*2*489.8*101.5*82.29*13*PVJLS03YP0000*13*7
    AMT*AU*489.8
    CAS*PR*2*82.29      <-- line moved here (XXX)
    REF*6R*00000000002
    DTM*472*20160528
    CAS*OA*23*306.01
    AMT*AU*489.8        <-- line previous to this deleted
    SVC*HC:99212:25*489.8*101.5**1
    AMT*B6*411.43
    
  3. ?^AMT\*AU?d생산하다

    CLP*815900102*2*489.8*101.5*82.29*13*PVJLS03YP0000*13*7
    CAS*PR*2*82.29      <-- the line before this was removed (XXX)
    REF*6R*00000000002
    DTM*472*20160528
    CAS*OA*23*306.01
    AMT*AU*489.8
    SVC*HC:99212:25*489.8*101.5**1
    AMT*B6*411.43
    

기억하기 쉬운 "문장"으로:

pat1='^AMT\*AU'; pat2='^CAS\*PR'; printf '/%s/t/%s/\n?%s?m/%s/\n?%s?d\nwq\n' "$pat1" "$pat2" "$pat2" "$pat1" "$pat1" | ed -s file

동일한 작업을 두 번째로 실행하면 되돌릴 수 있습니다. 즉, 어떤 모드가 첫 번째인지 두 번째인지는 중요하지 않습니다.

답변3

일치하는 라인을 홀딩 버퍼에 넣고 다음 라인을 읽고 인쇄한 다음 홀딩 버퍼를 패턴 버퍼로 바꾸고 다시 인쇄하여 원하는 효과를 얻을 수 있습니다.

bash-4.3$ sed -n '/^REF\*CE/!p;/^REF\*CE/{h;n;p;x;p}' input.txt
some line here
REF*BB*106497026---------------
REF*1W*723266637---------------
REF*CE*NEW JERSEY--------------
SVC*HC^S5102*78.5*78.5**1------
another line there

답변4

다음과 같은 간단한 해결책이 있습니다. "XXXX"가 포함된 파일의 줄을 "YYYY"가 포함된 줄로 바꾼 다음 "XXXX"가 포함된 한 줄과 "YYYY"가 포함된 한 줄만 제공한다고 가정해 보겠습니다.

샘플 파일은 다음과 같습니다: ssss dddd
aaaa ffff
ddd rrrr
ddddd XXXX
ddddde
ffff
ffff
fff
eeee YYYY
ghghgh
hhhhh

내 "sed" 명령은 sed 's/XXXX/ZZZZ/g;s/YYYY/XXXX/g;s/ZZZZ/YYYY/g'입니다. "ZZZZ" 문자열이 파일에 표시되어서는 안 된다는 점을 기억하세요.

관련 정보