Grep은 파일에서 텍스트를 찾아 텍스트의 처음 3줄을 인쇄합니다.

Grep은 파일에서 텍스트를 찾아 텍스트의 처음 3줄을 인쇄합니다.

파일이 있고 파일에서 여러 파일 이름을 찾고 있습니다. 검색 텍스트 예시 intl_reg.jcl. 일단 찾으면 그 위에 3줄의 텍스트를 가져와야 합니다. 예를 들어, 다음은 파일의 4줄입니다. "잔고 등록된 유학생"이라는 설명 앞의 텍스트는 항상 CHOICE이고 그 뒤에 설명이 옵니다.

CHOICE List registered international students with balances   
SHORTCUT 8  
PROCESS CHDIR /d3/locban/arsys  
PROCESS CMD ksh /d3/locban/arsys/intl_reg.jcl

다음과 같이 나열하려면 grep 명령이 필요합니다.

intl_reg.jcl  registered international students with balances

답변1

사용행복하다(이전 Perl_6)

~$ raku -e 'my @a; for lines() { 
            if @a.elems == 4 { @a.push($_); @a.shift } 
            elsif @a.elems < 4 { @a.push($_) }; 
            if .match( /intl_reg\.jcl/ ) and @a.elems == 4 {
            say $<>.Str, @a[0].split( /<?after List>/ ).[1] }; 
            };' file

즉, @a배열을 선언하고 lines명령줄에서 읽어옵니다. 입력은 4가 될 때까지 배열 push에 추가된 다음 최대 크기를 4 요소로 유지하기 위해 첫 번째 요소가 제거됩니다 .@aelemsshift

배열에 4개의 요소가 포함된 것으로 match확인 되면 일치하는 변수( 와 동일 )를 인쇄한 다음 3줄 전에 기록된 줄을 인쇄하여 원하는 문자열을 적절하게 반환합니다.and$<>$<>$/split

입력 예:

A CHOICE List registered international students with balances   
A SHORTCUT 8  
A PROCESS CHDIR /d3/locban/arsys  
A PROCESS CMD ksh /d3/locban/arsys/intl_reg.jcl
B CHOICE List registered international students with balances   
B SHORTCUT 8  
B PROCESS CHDIR /d3/locban/arsys  
B PROCESS CMD ksh /d3/locban/arsys/intl_reg.jcl

예제 출력:

intl_reg.jcl registered international students with balances   
intl_reg.jcl registered international students with balances  

https://raku.org

답변2

다음 awk프로그램이 작동합니다.

옵션 1: 듀얼 채널

awk -v d=3 -v s="intl_reg.jcl" '(NR==FNR) && index($0,s){i=FNR;nextfile} 
                                FNR==(i-d){printf "%s\t%s\n",s,$0; exit}' input.txt input.txt

여기서는 입력 파일을 두 번 지정하여 두 번 처리하도록 합니다. 검색할 문자열이 awk변수로 전달되고 s, 거리가 awk변수 로 전달됩니다 d.

  • 첫 번째 단계에서 NR전역 줄 카운터는 FNR파일별 줄 카운터와 동일하며 각 줄에 문자열이 있는지 확인됩니다. 발견되면 행 번호가 변수에 저장되고 i실행이 즉시 다음 파일(=동일 파일의 다음 반복)로 점프합니다.
  • 두 번째 패스에서 프로그램은 현재 줄 번호가 d이전에 인식된 패턴 발생 횟수( 에 저장되어 있음)보다 작은 지 확인합니다 i. 해당 줄이 발견되면 검색 문자열과 함께 인쇄되고 프로그램이 종료됩니다. 파일 부분의 나머지 부분을 유휴 상태로 순환하지 않도록 합니다.

옵션 2: 편도

프로세스 속도를 높이고 파일에 다시 액세스할 수 없는 경우(예: 파이프이기 때문에) 버퍼링이 포함된 단일 패스 솔루션을 사용할 수도 있습니다. 이 경우 특정 길이의 FIFO 버퍼가 필요합니다. 즉, d너무 크면 실용적이지 않습니다(그러나 문제가 되는 경우는 거의 없음).d

awk -v d=3 -v s="intl_reg.jcl" 'FNR>1{for (j=d;j>0;j--) {buf[j]=buf[j-1]}; buf[0]=$0}
                            FNR>d && match($0,s) {printf "%s\t%s\n",s,buf[d];exit}' input.txt

bufd+1그러면 버퍼 내용이 각 새 줄에서 "위로 이동"하고 현재 줄은 항상 마지막 몇 줄로 버퍼를 채울 것 입니다 buf[0]. 일단 검색 문자열이 발견되면 줄의 내용이 인쇄됩니다 buf[d]. 이는 d현재 줄 앞의 줄입니다. 이번에도 성능상의 이유로 프로그램이 즉시 종료됩니다.

답변3

match=intl_reg.jcl
tac {file} |
    sed -n "/$match/ { n; n; n; s/^CHOICE/$match/p }"

정규식 연산자를 $match포함 하거나 포함 하지 않도록 하세요 . /(이것은 .실제로 와일드카드이므로 이 규칙을 즉시 어기십시오. 이는 문제가 될 수도 있고 아닐 수도 있습니다.)

답변4

awk를 사용하십시오.

$ awk -v t='intl_reg.jcl' '{a[NR%4]=$0} index($0,t){$0=a[(NR-3)%4]; $1=$2=""; print t $0}' file
intl_reg.jcl  registered international students with balances

관련 정보