파일이 있습니다 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]
를 설정합니다.s
2
- 지금부터 결과를 인쇄하고 싶습니다.
- (처음에는) 인쇄하고 싶습니다두 번째 행(=필드)부터 시작처음으로 "제목" 행을 인쇄하고 싶기 때문입니다.
참고 가능한 후행 공백/탭을 방지하기 위해
$1 ~
전체 문자열 비교 대신 정규식 비교를 사용하고 있습니다 .$1==
설정된 경우
s
number 로 시작하는 필드(=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
{ 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/
첫 번째와 마지막은 정규식을 통해 액세스할 수 있는 범위의 경계 상자입니다 //
. 마찬가지로 내부는 를 통해 접근할 수 있습니다 //!
. 단, 이것이 범위를 입력할 때 사용하는 첫 번째 정규 표현식입니다.