패턴과 일치하는 연속 줄과 다음 3줄을 삭제합니다.

패턴과 일치하는 연속 줄과 다음 3줄을 삭제합니다.

다음 내용이 포함된 파일이 있습니다.

dn : Does not matter
 uid=321 456 678
foo=/234
bar=/456
git=/543

 uid=321 456 678
 uid=678 987 098
foo=/234
bar=/456
git=/543

dn : Does it matter
 uid=321 456 678
foo=/543
bar=/423
git=/501

uid=예상되는 출력이 다음과 같도록 연속된 항목과 그 뒤의 3줄을 제거하고 싶습니다 .

 dn : Does not matter
 uid=321 456 678
foo=/234
bar=/456
git=/543

dn : Does it matter
 uid=321 456 678
foo=/543
bar=/423
git=/501

두 개의 서버에서 이것을 시도했습니다. 안타깝게도 제가 가장 많이 사용해 본 서버에는 액세스할 수 없습니다. 그래서 두 번째 서버에서는 다음과 같은 다양한 변형을 시도했지만 원하는 결과를 얻을 수 없었습니다.

sed '/^ uid=/N;{/\n uid= & & \n ^change type & & \n ^replace/d;}' pattern2.txt
awk '{/pat/?f++:f=0} f==2 {f--;}; 1' < pattern2.txt
sed '/^ uid=/N;{/\n uid=/D;}' pattern1.txt
awk '{/ uid=/?f++:f=0} f==2' pattern1.txt

답변1

사용 sed:

$ sed -f script.sed file
dn : Does not matter
 uid=321 456 678
foo=/234
bar=/456
git=/543

dn : Does it matter
 uid=321 456 678
foo=/543
bar=/423
git=/501

... script.sed어디

H              # Append a newline and the current line to the hold space
/^$/bout       # Empty line: branch to ':out'
$bout          # Last line: branch to ':out'
d              # Delete line, start again from the top
:out
x              # Swap in the data from the hold space
/uid.*uid/d    # Delete the data if it contains two "uid"
s/\n//         # Remove the first embedded newline
               # (implicit print)

이는 sed"예약된 공간"(일반 버퍼)에 읽은 줄을 수집하고, 빈 줄이나 입력 끝을 만나면 예약된 공간에는 원본 파일의 "청크" 중 하나가 포함됩니다. 이러한 블록에 문자열 인스턴스가 두 개 포함되어 있으면 uid해당 블록은 삭제되고, 그렇지 않으면 출력됩니다.

답변2

나는 이것이 단순화될 수 있다고 생각 awk하지만 아직은 그렇지 않다.

awk '/uid=/ && p~/uid=/{c=4; next}
     !(c && c--) && NR>1{print p} {p=$0}
     END{if(c==0)print p}' ip.txt
  • 기본적으로 awk의 초기화되지 않은 변수는 상황에 따라 빈 문자열 또는 0이 됩니다.
  • /uid=/ && p~/uid=/현재 줄과 이전 줄에 다음이 포함되어 있는 경우uid=
    • c=4; next건너뛸 행 수 c(최종 논리로 인해 1 추가)로 초기화합니다. 또한 나머지 코드는 건너뛰세요.
  • !(c && c--) && NR>1{print p}현재 줄 번호가 1보다 크면 이전 줄을 인쇄합니다 c==0. c보다 크면 계속 0감소합니다.c==0
  • {p=$0}나중에 사용할 수 있도록 이전 줄을 저장하세요.
  • END{if(c==0)print p}다음과 같은 경우 마지막 줄을 인쇄하세요.c==0

관련 정보