패턴을 찾아 앞 2줄, 뒤 1줄의 시작 부분에 #을 삽입하세요.

패턴을 찾아 앞 2줄, 뒤 1줄의 시작 부분에 #을 삽입하세요.

큰 파일(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첫 번째 \newline에 인쇄한 다음 D첫 번째 \newline으로 이동하고 주기를 다시 시작합니다.

답변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/newwhere와 비슷합니다. old우리의 경우에는 입니다 \n([^\n]*)\n([^\n]*)\n([^\n]*Fail[^\n]*)\n. 이를 네 부분으로 나누어 보겠습니다.

    1. \n([^\n]*)첫 번째 행을 찾아 그룹 1에 저장합니다.

    2. \n([^\n]*)두 번째 행을 찾아 그룹 2에 저장합니다.

    3. \n([^\n]*Fail[^\n]*)세 번째 줄을 찾습니다. 단, 해당 줄에 단어가 포함된 경우에만 일치합니다 Fail.

    4. \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'

관련 정보