일치하는 행 뒤의 행만 표시하는 방법은 무엇입니까?

일치하는 행 뒤의 행만 표시하는 방법은 무엇입니까?

파일이 있습니다 A.tsv(필드 구분 기호 = \t).

for Research Use Only                       
                        
[Header]                        
Test Name   Il          
Run ID  2102                
Run Date    2021-02-04                  
Report Date/Time    2021-02-05 08:48                    
Instrument Serial                       
Flow Cell ID                    
Software Version                    
                        
[Quality Control]                       
Lane 1,2,3,4    PASS                    
Lane 1,2,3,4 Index Set 1    PASS                    
                        
[Patient Sample Results]                        
Sample ID   Internal Control    Result  Consensus Sequence  Lane    Index Set   Index ID
207 Pass        Not Available   1,2,3,4 1   UDP0001
205 Pass        Not Available   1,2,3,4 1   UDP0002

[Control Sample Results]                        
Sample ID   Control Type    Human Control   SARS-CoV-2  Lane    Index Set   Index ID
CONTROL-POS Positive Control    Not Detected    Detected    1,2,3,4 1   UDP0008

새 파일에 다음 줄을 인쇄하고 싶습니다.

Sample ID   Internal Control    Result  Consensus Sequence  Lane    Index Set   Index ID
207 Pass        Not Available   1,2,3,4 1   UDP0001
205 Pass        Not Available   1,2,3,4 1   UDP0002
CONTROL-POS Positive Control    Not Detected    Detected    1,2,3,4 1   UDP0008

[Patient Sample Results]그래서 and 뒤에 있는 줄을 인쇄하고 싶지만 [Control Sample Results]헤더 줄은 한 번만 인쇄하고 싶습니다.

파일은 서브샘플링되어 행 번호로 하드코딩될 수 없습니다.

그래서 나는 다음과 같은 것을 시도했습니다.

awk '/Patient Sample Results/{getline; print}' A.tsv > data_info.tsv

하지만 첫 번째 패턴 이후의 줄만 인쇄합니다. 내 문제에 대한 해결책이 있나요?

답변1

섹션 [ ... ]이 빈 줄(공백/탭을 포함할 수 없습니다.), 그리고 로 시작하는 모든 섹션의 내용을 인쇄하려면 [Patient Sample Results]다음이 작동해야 합니다.

awk -F"\n" -v RS="" '$1~/^\[Patient Sample Results\]/{s=2}
                     s{for (i=s;i<=NF;i++) print $i; s=3}' A.tsv > data_info.tsv

이는 "단락 모드"에서 작동하도록 지시하며 awk빈 줄 그룹을 레코드 구분 기호로 처리하고 줄 바꿈을 필드 구분 기호로 처리합니다.

  • $1이제 "장 제목"이 레코드의 첫 번째 "필드"( ) 로 표시됩니다 .

  • 첫 번째 필드(=행) 또는 레코드가 로 시작되면 이를 나타내는 플래그 [Patient Sample Results]를 설정합니다.s2

    1. 지금부터 결과를 인쇄하고 싶습니다.
    2. (처음에는) 인쇄하고 싶습니다두 번째 행(=필드)부터 시작처음으로 "제목" 행을 인쇄하고 싶기 때문입니다.

    참고 가능한 후행 공백/탭을 방지하기 위해 $1 ~전체 문자열 비교 대신 정규식 비교를 사용하고 있습니다 .$1==

  • 설정된 경우 snumber 로 시작하는 필드(=line)를 인쇄합니다 s(처음에는 2임). 그런 다음 나중에 "Header" 행을 건너뛸 수 있도록 3으로 설정합니다.

필드(= 줄)는 "있는 그대로" 인쇄되므로 입력 파일에 있는 구분 기호가 유지됩니다.

섹션이 실제로 공백이 포함된 "빈" 줄로 구분된 경우, 다중 문자 레코드 구분 기호에 대해 GNU를 요구하는 다음 수정 사항을 사용하면 awk이러한 일이 발생하지 않습니다(참조:StackOverflow에 대한 @EdMorton의 답변예를 들어):

awk -F'\n' -v RS='\n(([[:space:]]*\n)+|$)' ' ... '

이는 "완전히 비어 있거나 공백 문자만 포함하는" 숫자를 레코드 구분 기호로 처리합니다.

답변2

어쩌면 좋아

awk 'BEGIN {FS="\t"}
     /^\[Patient Sample Results]/ { printing=1 ; next }
     !printing { next }
     /^\[/ { next }
     /^[ \t]*$/ { next }
     /^Sample/ { if (!printedheader) { print }; printedheader=1 ; next }
     { print }'
  1. 필드 구분 기호를 실제로 필요하지 않은 탭으로 설정합니다.
  2. 인쇄를 시작해야 할 때를 참고하세요
  3. 아직 인쇄하지 않았다면 다음 줄로 이동하세요.
  4. 다음으로 시작하는 줄을 인쇄하지 마세요.[
  5. 공백과 탭으로만 정의된 빈 줄을 건너뜁니다.
  6. 헤더인 경우 처음 볼 때 인쇄한 후 다음 줄로 이동하세요.
  7. 나머지를 인쇄하세요

.1{ print }

편집하다. 주석에 대한 응답으로 빈 줄의 정의가 변경되었습니다.

답변3

노력하다:

awk '/\[(Patient|Control) Sample Results\]/{ hdr++; next }
     hdr==2        { hdr--; next }
     hdr && !rep   { print; rep=1; next }
     rep && $0!="" { print }
' infile

답변4

이를 사용하여 GNU sed다음을 수행할 수 있습니다. 환자 또는 대조군 샘플 결과가 구성 파일 A.tsv에 나열되어 있는지 여부는 중요하지 않습니다.

sed -En '
  /\[(Patient|Control) Sample Results]/,/^\s*$/{
    //!{p;d;}
    /\S/!d;n;G
    /\n./n;P;h
  }
' A.tsv

일부 용어: 일련의 줄에서 /begin/,/end/첫 번째와 마지막은 정규식을 통해 액세스할 수 있는 범위의 경계 상자입니다 //. 마찬가지로 내부는 를 통해 접근할 수 있습니다 //!. 단, 이것이 범위를 입력할 때 사용하는 첫 번째 정규 표현식입니다.

관련 정보