큰 파일(2000줄 이상)이 있습니다. 패턴을 찾은 후 위 2줄, 아래 1줄 시작 부분에 #을 넣어야 합니다. 또한 패턴이 발견된 줄의 시작 부분에 #을 삽입하세요. 환경은 Red Hat Linux입니다. 또, 설명도 해주시면 좋을 것 같아요.
예를 들어, 다음 텍스트를 참조하여 "Fail"을 검색하고 해당 문자열 앞의 #2 줄과 그 뒤의 #1 줄(줄의 시작 부분)을 검색하세요. 또한 # 줄에는 "Fail"이라는 문자열이 포함되어 있습니다.
Name
Number
Reason = Pass
Reasult
Name
Number
Reason = Pass
Reasult
Name
Number
Reason = Fail
Reasult
Name
Number
Reason = Pass
Reasult
Name
Number
Reason = Fail
Reasult
Name
Number
Reason = Pass
Reasult
답변1
다음을 사용하는 것이 좋습니다 perl
.
perl -p0e 's/(.*\n)(.*\n)(.*Fail\n)/#\1#\2#\3#/g' file
작동 방식은 다음과 같습니다.
-p
: 모든 입력 라인에 걸쳐 인쇄 프로그램을 반복합니다.-0
: 레코드 구분 기호로 null을 가정합니다.-e
: 명령줄에서 프로그램 실행s/x/y/g
: 파일의 어느 곳에서나 x를 y로 바꿉니다.()
: 정규 표현식을 함께 결합.*
: 개행 문자를 제외한 모든 문자가 0번 이상 반복됩니다.\n
: 새로운 팀\1
,\2
,\3
: n번째 그룹의 접근 모드()
산출:
Name
Number
Reason = Pass
Reasult
Name
Number
Reason = Pass
Reasult
#Name
#Number
#Reason = Fail
#Reasult
Name
Number
Reason = Pass
Reasult
#Name
#Number
#Reason = Fail
#Reasult
Name
Number
Reason = Pass
Reasult
답변2
다음은 sed
슬라이딩 창을 사용하는 솔루션입니다(따라서 한 번에 패턴 공간에 4개 이상의 선이 표시되지 않음).
sed '1{N;N;};$!N;/.*\n.*\n.*Fail.*\n.*/{s/^/#/;s/\n/&#/g;};P;D' infile
첫 번째 줄에서는 N
다음 두 줄을 읽습니다(따라서 이제 패턴 공간에는 세 줄이 있습니다).
그런 다음 모든 입력 라인(첫 번째 라인 포함)에 대해 N
추가 라인을 가져옵니다(따라서 이제 패턴 공간에는 4개의 라인이 있습니다). 패턴 공간의 세 번째 라인이 일치하면 Fail
패턴 공간의 각 라인 앞에 라인을 추가합니다 #
. 그런 다음 무슨 일이 있어도 P
첫 번째 \n
ewline에 인쇄한 다음 D
첫 번째 \n
ewline으로 이동하고 주기를 다시 시작합니다.
답변3
$ sed -r 'H;1h;$!d;x; s/\n([^\n]*)\n([^\n]*)\n([^\n]*Fail[^\n]*)\n/\n#\1\n#\2\n#\3\n#/g' file
Name
Number
Reason = Pass
Reasult
Name
Number
Reason = Pass
Reasult
#Name
#Number
#Reason = Fail
#Reasult
Name
Number
Reason = Pass
Reasult
#Name
#Number
#Reason = Fail
#Reasult
Name
Number
Reason = Pass
Reasult
어떻게 작동하나요?
H;1h;$!d;x
이 명령은 전체 파일을 읽습니다.
s/\n([^\n]*)\n([^\n]*)\n([^\n]*Fail[^\n]*)\n/\n#\1\n#\2\n#\3\n#/g
Fail
세 번째 행에서 4개의 연속 행을 찾습니다. 발견되면#
각 개행 문자 뒤에 배치됩니다.좀 더 자세히 살펴보면 교체 명령은 정규식
s/old/new
where와 비슷합니다.old
우리의 경우에는 입니다\n([^\n]*)\n([^\n]*)\n([^\n]*Fail[^\n]*)\n
. 이를 네 부분으로 나누어 보겠습니다.\n([^\n]*)
첫 번째 행을 찾아 그룹 1에 저장합니다.\n([^\n]*)
두 번째 행을 찾아 그룹 2에 저장합니다.\n([^\n]*Fail[^\n]*)
세 번째 줄을 찾습니다. 단, 해당 줄에 단어가 포함된 경우에만 일치합니다Fail
.\n
네 번째 개행 문자와 일치합니다. (네 번째 줄의 텍스트는 저장되지 않습니다. 필요하지 않습니다.)
위와 일치하는 줄이 4개 있으면 각 줄 뒤에 추가된 개행 문자를
\n#\1\n#\2\n#\3\n#
제외하고 입력과 동일한 내용 으로 바꿉니다 .#
\n
맥오에스엑스(BSD)
위의 내용은 GNU sed에서 테스트되었습니다. BSD sed를 사용하는 경우 다음을 시도하십시오.
sed -E 'H;1h;$!d;x; s/\n([^\n]*)\n([^\n]*)\n([^\n]*Fail[^\n]*)\n/\n#\1\n#\2\n#\3\n#/g' file
답변4
더 간단한 변형@don_crissti스크립트
sed ':a;/\(.*\n\)\{2\}/{P;D};N;/= Fail$/! ba;N;s/^/# /gm'