내 파일에는 아래와 같이 수백만 개의 레코드가 있습니다.
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+2
-n
처리할 최대 다음 행 수를 설정합니다(다음 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 }
- 처리된 섹션 아래의 라인 3에 다음이 포함된 경우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
설명하다:
RS='echo "NEW Cell"\n'
-RS
입력 레코드 구분 기호이며 기본값은 개행입니다. 이제 대신echo "NEW Cell"\n
해당 문자열의 모든 항목이 삭제되고 그 사이의 모든 문자가 레코드 항목이 됩니다./\n.+\n/{
- 개행, 하나 이상의 문자, 개행 등 이 패턴과 일치하는 레코드에만 적용됩니다. 따라서 여러 줄 레코드만 일치하고, 한 줄 레코드는 하나만 있으므로 일치하지 않습니다\n
.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