두 줄 사이의 한 줄을 제거하는 방법

두 줄 사이의 한 줄을 제거하는 방법

파일에 다음과 같은 수백만 개의 레코드가 있습니다.

echo "NEW Cell"
grep "2553,24" out.2A25.20090308.64436.7.HDF.txt.text = 22.58   5.39  82.09 237
echo "NEW Cell"
grep "2555,20" out.2A25.20090308.64436.7.HDF.txt.text = 24.72   5.58  82.05 237
echo "NEW Cell"
grep "2557,20" out.2A25.20090308.64436.7.HDF.txt.text = 19.75   5.62  82.11 170
grep "2557,21" out.2A25.20090308.64436.7.HDF.txt.text = 24.34   5.58  82.13 120
grep "2558,22" out.2A25.20090308.64436.7.HDF.txt.text = 22.2   5.57  82.19 120
echo "NEW Cell"
grep "2560,22" out.2A25.20090308.64436.7.HDF.txt.text = 24.69   5.62  82.25 160
grep "2561,23" out.2A25.20090308.64436.7.HDF.txt.text = 24.74   5.60  82.30 120
echo "NEW Cell"
grep "2560,24" out.2A25.20090308.64436.7.HDF.txt.text = 19.38   5.54  82.30 170
echo "NEW Cell"

이제 "New Cell"을 포함하는 줄 사이의 유일한 줄이라는 조건에서 "grep"을 사용하여 줄을 삭제하고 싶습니다. 즉, 새 셀 사이에 grep 줄이 하나 있으면 이 줄을 삭제해야 합니다.

어떻게 해야 하나요?

내 출력은 다음과 같습니다.

echo "NEW Cell"
grep "2557,20" out.2A25.20090308.64436.7.HDF.txt.text = 19.75   5.62  82.11 170
grep "2557,21" out.2A25.20090308.64436.7.HDF.txt.text = 24.34   5.58  82.13 120
grep "2558,22" out.2A25.20090308.64436.7.HDF.txt.text = 22.2   5.57  82.19 120
echo "NEW Cell"
grep "2560,22" out.2A25.20090308.64436.7.HDF.txt.text = 24.69   5.62  82.25 160
grep "2561,23" out.2A25.20090308.64436.7.HDF.txt.text = 24.74   5.60  82.30 120

답변1

AWK해결책:

awk 'NR==n{ if (/NEW Cell/) { f=0 } else print r ORS gr }
     /NEW Cell/{ f=1; n=NR+2; r=$0; next }
     f && n-NR==1 && /^grep /{ gr=$0; next }1' file
  • /NEW Cell/{ f=1; n=NR+2; r=$0; next }- 와 마주치는 중NEW Cell

    • f=1= 활성 플래그 설정f=1
    • n=NR+2n- 처리할 다음 라인의 최대 개수로 설정 (다음 라인 2개)
    • r=$0- 줄을 잡는다
    • next- 다음 레코드로 점프
  • f && n-NR==1 && /^grep /- 키워드 n-NR==1로 시작하는 두 번째 줄( 로 보장)을 만났을 때grep

    • gr=$0; next- grep라인을 캡처하고 다음(세 번째) 레코드로 점프
  • NR==n{ if (/NEW Cell/) { f=0 } else print r ORS gr }- 세 번째 중요한 라인을 만날 때(에 의해 보장됨 NR==n)

    • if (/NEW Cell/) { f=0 }- 처리된 섹션 아래의 세 번째 라인에 다음이 포함된 경우 NEW Cell- 현재 처리를 재설정합니다 f=0(이전에 캡처된 모든 라인을 건너뜁니다).
    • else print r ORS gr- 그렇지 않으면 이전에 캡처한 모든 라인을 인쇄합니다.

출력:

echo "NEW Cell"
grep "2557,20" out.2A25.20090308.64436.7.HDF.txt.text = 19.75   5.62  82.11 170
grep "2557,21" out.2A25.20090308.64436.7.HDF.txt.text = 24.34   5.58  82.13 120
grep "2558,22" out.2A25.20090308.64436.7.HDF.txt.text = 22.2   5.57  82.19 120
echo "NEW Cell"
grep "2560,22" out.2A25.20090308.64436.7.HDF.txt.text = 24.69   5.62  82.25 160
grep "2561,23" out.2A25.20090308.64436.7.HDF.txt.text = 24.74   5.60  82.30 120

답변2

다음 을 갖춘 컴팩트 솔루션 sed:

sed '/NEW Cell/!{H;d;};x;/\n.*\n/!d'

라인에 NEW Cell실행이 포함되어 있지 않으면 H보류 공간에 라인을 추가하고 d해당 라인에 대한 처리를 중지합니다.

NEW Cell따라서 추가 명령은 라인 에만 적용됩니다 . x패턴 공간과 홀드 공간을 교환하므로 라인은 이제 홀드 공간에 있고 추가 라인을 추가할 수 있으며 패턴 공간에는 마지막 NEW Cell라인에 추가된 모든 것이 포함됩니다. 요구 사항은 줄 사이에 두 개 이상의 줄이 있어야 하므로 NEW Cell패턴 공간에 개행 문자가 두 개 이상 있어야 합니다. 그렇지 않은 경우 출력 없이 삭제하세요 /\n.*\n/!d.

답변3

초보적인 것으로 awk...

grep버전 1은 OP 설명을 따르는 줄만 삭제합니다 .

awk '/^grep/ { if (f) { if (length(s) > 0) { print s; s="" } print } \
     else { f=1; s=$0 } } ! /^echo/ { print; f=0 } \
     ! /^echo/ && ! /^grep/ { print }' inputfile

grep버전 2 는 OP의 샘플 출력을 따르는 이전의 비 grep 행뿐만 아니라 솔로 행도 삭제합니다 .

awk '/^grep/ { if (f) { if (length(s) > 0) { print s; s="" } print } \
    else { f=1; s=s "\n" $0 } } /^echo/ { s=$0; f=0 } \
    ! /^echo/ && ! /^grep/ { print }' inputfile

버전 2의 읽을 수 있는 형식...

/^grep/ { 
   if (found) {  # found==true : already encountered first grep line
       if (length(save) > 0) {
          print save
          save=""
       }
       print
   } else {
       found=1
       save=save "\n" $0  # append the first grep line to saved preceding line
   }
}

/^echo/ { 
    save=$0  # save this line for possible later printing
    found=0
}

# print anything else
! /^echo/ && ! /^grep/ { print }

이 긴 형식은 파일(예: awkfile) 및 awk -f awkfile inputfile.

답변4

gawk '
/\n.+\n/{
    printf("%s%s", RS, $0);
}' RS='echo "NEW Cell"\n' input.txt

설명:

  1. RS='echo "NEW Cell"\n'- RS입력 레코드 구분 기호이며 기본적으로 개행입니다. 이제 로 변경되었으므로 echo "NEW Cell"\n이 문자열의 모든 항목이 제거되고 그 사이의 모든 문자가 레코드 항목이 됩니다.
  2. /\n.+\n/{- 이 패턴과 일치하는 레코드에만 해당됩니다(개행, 하나 이상의 문자, 개행). 따라서 여러 줄 레코드에만 일치하고 단일 줄 레코드는 하나만 있기 때문에 일치하지 않습니다 \n.
  3. printf("%s%s", RS, $0);RS- ( ) 앞에 기록을 인쇄합니다 echo "NEW Cell"\n.

산출

echo "NEW Cell"
grep "2557,20" out.2A25.20090308.64436.7.HDF.txt.text = 19.75   5.62  82.11 170
grep "2557,21" out.2A25.20090308.64436.7.HDF.txt.text = 24.34   5.58  82.13 120
grep "2558,22" out.2A25.20090308.64436.7.HDF.txt.text = 22.2   5.57  82.19 120
echo "NEW Cell"
grep "2560,22" out.2A25.20090308.64436.7.HDF.txt.text = 24.69   5.62  82.25 160
grep "2561,23" out.2A25.20090308.64436.7.HDF.txt.text = 24.74   5.60  82.30 120

관련 정보