패턴A를 일치시키고 다음 줄을 포함하여 패턴B가 일치할 때만 인쇄합니다.

패턴A를 일치시키고 다음 줄을 포함하여 패턴B가 일치할 때만 인쇄합니다.

나는 'search_string'이라는 단어 + 그 뒤의 줄 + 그 앞에 'mod'와 일치하는 줄이 있는 모든 줄을 얻으려고 합니다.
나는 시도했다:

grep -n 'mod\|search_string' ip | grep --before 1 search_string> inter  
grep -n --after 1 search_string ip >> inter  
sort -t':' -k1,1n -u inter -o op

더 좋은 방법이 있나요?

파일:

mod start1  
some lines  
mod start2  
other lines  
mod start3  
 many other lines  
 search_string yada yada  
 hello  
 many other lines  
 search_string yada yada  
 bye  
mod start4  
 search_string baba baba  
 this too  
mod start5  

예상 출력:

mod start3  
 search_string yada yada   
 hello  
 search_string yada yada  
 bye  
mod start4  
 search_string baba baba  
 this too

답변1

awk '
   $0 ~ /mod/ { md=$0 }
   $0 ~ /search_string/ { if(md!="") { print md }; md="" ; print; getline; print }
   '

설명:

  • 다음을 포함하는 행 mod은 로 저장됩니다 md.
  • search_string이전에 저장된 md, 라인 자체 및 다음 라인을 인쇄하는 트리거를 포함하는 라인입니다 .
  • if(md!="")단일 항목 아래에 -s가 많이 있을 때 ( 귀하의 예에서는) md=""중복된 줄이 생기지 않도록 하기 위해 거기에 있습니다 .modsearch_stringmodmod start3

메모:

  • 두 가지를 모두 포함하는 줄은 modsearch_string논리를 깨뜨립니다.

답변2

파일에 "캐리지 리턴" 문자가 포함되어 있습니다. Unix에서는 제거하는 것이 좋습니다. 게시한 명령 순서를 인쇄하려면(캐리지 리턴을 제거한 상태로) 다음을 시도하십시오.

awk '{gsub(/\r/,"")}
     /mod/          { a = $0 }
     /search_string/{ if(a!=""){print(a);a=""}
                      print;getline;print
                    }
    ' infile

또는 한 줄로:

$ awk '{gsub(/\r/,"")}/mod/{a=$0}/search_string/{if(a!=""){print(a);a=""}print;getline;print}' infile

mod start3  
 search_string yada yada  
 hello  
 search_string yada yada  
 bye  
mod start4  
 search_string baba baba  
 this too  

(GNU) awk에서 다중 문자 레코드 구분 기호를 사용할 수 있으므로 레코드 구분 기호를 로 설정 mod하고 search_string. 원본 레코드를 재구성하려면 printf가 필요합니다.

"예상 출력"으로 게시한 내용을 인쇄하려면 다음을 시도하십시오.

awk '/search_string/{printf("mod%s", $0)}' RS=mod infile

답변3

Python 스크립트에서 이를 원하는 경우:

# Read file into memory.
with open('myfile.txt') as f:
    lines = [line.rstrip() for line in f]

# Loops through lines backwards, looking for string and optionally mod.
output_lines = list()
find_mod = False
for i, line in enumerate(lines[::-1]):
    if 'search_string' in line:
        output_lines.append(lines[::-1][i-1])
        output_lines.append(lines[::-1][i])
        find_mod = True
    elif find_mod and 'mod' in line:
        output_lines.append(lines[::-1][i])
        find_mod=False

print("\n".join(output_lines[::-1]))

관련 정보