특정 패턴을 찾은 후 중간에 한 줄을 건너뛰고 데이터 파일의 값을 인쇄하려면 어떻게 해야 합니까?

특정 패턴을 찾은 후 중간에 한 줄을 건너뛰고 데이터 파일의 값을 인쇄하려면 어떻게 해야 합니까?

이라는 파일이 있습니다 File-1. 패턴을 일치시켜야 DATA_POINTS하고 행을 건너뛴 후 다음 행의 여섯 번째 열을 인쇄하려고 합니다.

  • File-1예:
    here ! some other data exist but all of them are totally different from the below data!
    
    In simple words following data is completely unique.
    
    
    DATA_POINTS
    12
       0.0000000000     0.0000000000     0.0000000000  20   !  A
       0.5000000000     0.5000000000     0.0000000000  20   !  B
       0.7500000000     0.5000000000     0.2500000000  20   !  C
       0.7500000000     0.3750000000     0.3750000000  20   !  D
       0.0000000000     0.0000000000     0.0000000000  20   !  E
       0.5000000000     0.5000000000     0.5000000000  20   !  F
       0.6250000000     0.6250000000     0.2500000000  20   !  U
       0.7500000000     0.5000000000     0.2500000000  20   !  W
       0.5000000000     0.5000000000     0.5000000000  20   !  L
       0.7500000000     0.3750000000     0.3750000000  20   !  K
       0.6250000000     0.6250000000     0.2500000000  20   !  U
       0.5000000000     0.5000000000     0.0000000000  20   !  X
    
  • 원하는 출력
    S1 = A
    S2 = B
    S3 = C
    S4 = D
    S5 = E
    S6 = F
    S7 = U
    S8 = W
    S9 = L
    S10= K
    S11= U
    S12= X
    

패턴은 DATA_POINTS파일에서 반복되지 않으며 정확히 일치해야 합니다.

최근 솔루션

다른 qsn에서 이 명령을 받았습니다. 열 6이 동일한 행 패턴에 있는 경우에 작동합니다.

awk '/DATA_POINTS/{i==0 ; i++; getline; print "S"i"=", $6}' File-1

답변1

다음 awk프로그램이 작업을 수행해야 합니다.

awk 'BEGIN{n=-1}
     n>0{printf "S%-*d=%s\n",w,++i,$6; if (i==n) {i=0;n=-1}}
     n==0{n=$1;w=length($1)}
     $0=="DATA_POINTS"{n=0}' file

이는 다음을 수행합니다.

  • 처음에는 "데이터 블록 외부"를 의미하는 n"상태 플래그"가 초기화됩니다 .-1
  • DATA_POINTS문자열로만 구성된 행을 발견하면 "다음 행에 데이터 포인트 수가 포함됩니다"라는 의미로 n로 설정합니다.0
  • 0 인 경우 n행의 내용은 데이터 포인트 수로 해석되어 에 저장됩니다 n. 숫자의 길이(문자/숫자)는 w나중에 출력 형식을 지정하는 데 사용되는 필드에 저장됩니다.
  • n보다 크면 " 0데이터" 블록 내부에 있음을 나타내며 count 변수 i(고정 너비로 ​​서식 지정 w및 출력 예에서 왼쪽으로 조정)와 i같을 때까지 행의 6번째 필드를 사용하여 "키"를 인쇄합니다 n. 재설정n-1

이는 파일 끝에 있지 않은 데이터 덩어리를 처리할 수 있기 때문에 필요한 것보다 더 강력할 수 있습니다(단순히 파일 끝까지 읽는 것이 아니라 헤더에 지정된 데이터 줄 수를 존중합니다).

노트현재 검색 방법은 DATA_POINTS전체 문자열 일치이며, 이는 실제 문자열에 특수 문자가 포함될 수 있는 경우 가장 강력한 방법입니다. 부분 문자열 일치 또는 정규식 일치를 원하면 다음을 사용하십시오.

index($0,"DATA_POINTS") { ... }

또는 (귀하의 예에서와 같이)

/DATA_POINTS/ { ... }

또한 빈 줄의 오해를 방지하려면 및 를 n>0각각 n==0으로 바꾸십시오 .n>0&&NFn==0&&NF

답변2

$ awk '/DATA_POINTS/{c=3} c&&!--c{f=1} f{printf "S%d = %s\n", ++s, $6}' file
S1 = A
S2 = B
S3 = C
S4 = D
S5 = E
S6 = F
S7 = U
S8 = W
S9 = L
S10 = K
S11 = U
S12 = X

3행 대신 일치하는 행(포함)의 27행에서 인쇄를 시작하려면 3을 27로 변경하면 됩니다.

바라보다https://stackoverflow.com/questions/17908555/printing-with-sed-or-awk-a-line-following-a-matching-pattern/17914105#17914105위의 방법에 대한 자세한 정보와 게임이 끝난 후 수행할 수 있는 더 많은 방법을 알아보세요.

답변3

범위 연산자를 사용합니다 ,. 데이터 포인트 행으로 시작하고 eof로 끝납니다.

awk '
 /DATA_POINTS/,0 {
    if ( /DATA_POINTS/ ) {
      getline; next 
   }
   printf "S%-2d=%s%s\n", ++k, OFS, $6
 }
' file

답변4

이것은 sed를 사용하여 줄 번호, bc + 2, tail을 사용하여 데이터 덩어리를 추출하고 마지막으로 awk를 사용하여 올바른 열을 얻는 한 줄 솔루션입니다. 아마도 가장 깨끗하거나 간단한 솔루션은 아니지만 나에게는 awk를 사용하는 것보다 더 깨끗합니다.

sed -n '/DATA_POINTS/=' $file | xargs -i echo '{}+2' | bc | xargs -i tail -n+{} $file | awk '{print $6}'

관련 정보