여러 파일을 구문 분석하여 특정 줄을 추출하고 다른 파일로 출력하려고 합니다. 그러나 내 파일에서 이 정보의 위치는 특정 매개변수에 따라 변경될 수 있습니다.
이를 위해 나는 사용하고 싶습니다if 문. 대부분의 경우 추출해야 할 내용은 6행과 7행에 있습니다.
# IGBLASTN 2.5.1+
# Query: RL0575_B2_no210_RL0575_B2_ACPA_positive_LC
# Database: human_gl_V human_gl_D human_gl_J BCR_C_all.fa
# Domain classification requested: imgt
# V-(D)-J rearrangement summary for query sequence (Top V gene match, Top J gene match, Chain type, stop codon, V-J frame, Productive, Strand). Multiple equivalent top matches having the same score and percent identity, if present, are$
IGLV4-69*01 IGLJ1*01 VL No In-frame Yes +
이를 위해 나는 이렇게 합니다:
a=`ls *LC.fa | awk -F "." '{print $1}'`; #here i just strip the name of the files for the loop
for i in $a;
do cat $i.fmt7 | awk 'NR==6, NR==7' > $i.parsed.txt;
done
그러나 경우에 따라 6행에 추가 설명이 있기 때문에 파일의 8행과 9행에 이 정보가 포함됩니다.
# IGBLASTN 2.5.1+
# Query: RL0624_B10_no15_RL0624_B10_ACPA_positive_LC
# Database: human_gl_V human_gl_D human_gl_J BCR_C_all.fa
# Domain classification requested: imgt
# Note that your query represents the minus strand of a V gene and has been converted to the plus strand. The sequence positions refer to the converted sequence.
# V-(D)-J rearrangement summary for query sequence (Top V gene match, Top J gene match, Chain type, stop codon, V-J frame, Productive, Strand). Multiple equivalent top matches having the same score and percent identity, if present, are$
IGKV3-20*01 IGKJ2*01 VK Yes In-frame No -
위와 비슷한 방법으로 하고 싶지만
a=`ls *LC.fa | awk -F "." '{print $1}'`; #here i just strip the name of the files for the loop
for i in $a;
if [my condition?] # <== here I do not know how to formulate the condition!
then
cat $i.fmt7 | awk 'NR==8, NR==9'
else
cat $i.fmt7 | awk 'NR==6, NR==7' > $i.parsed.txt;
fi
done
서로 다른 프리앰블 길이에도 불구하고 올바른 행이 추출되도록 하려면 어떻게 해야 합니까? 이러한 파일에는 여기에 표시된 것보다 더 많은 데이터 행이 포함되어 있으므로 마지막 두 행보다 더 많은 행을 추출해야 합니다.
어떤 아이디어라도 대단히 감사하겠습니다.
답변1
파일에 관련 데이터 줄이 하나 포함되어 있고 나머지는 비어 있거나 #
;로 시작하는 주석 줄이 있는 것 같습니다. 그러나 마지막 것은 유지하려는 헤더입니다. 문제는 주석 줄 수가 다른 것 같습니다.
작업이 실제로 "구문 분석된" 요약 파일로 출력하기 위해 헤더와 이 데이터 라인을 추출하는 것이라면 다음과 같이 시작 패턴으로 식별된 헤더 이외의 awk
문자로 시작하는 모든 빈 라인 또는 라인을 무시하도록 지시할 수 있습니다 .#
# V-(D)-J
awk '$0~/^# V-\(D\)-J/ || ($0!~/^#/ && NF>0) {print}' input_file > parsed_file
반면, 파일에 여러 데이터 행이 포함되어 있고 헤더와 첫 번째 데이터 행만 인쇄하려는 경우 명령은 awk
다음과 같아야 합니다.
awk '$0~/^# V-\(D\)-J/ {print} ($0!~/^#/ && NF>0) {print;exit}' input_file > parsed_file
쉘 루프에서 이 작업을 수행하려면 다음을 수행하십시오.
for file in *LC.fa
do
infile="${file%.*}.fmt7"
outfile="${file%.*}.parsed.txt"
awk '$0~/^# V-\(D\)-J/ || ($0!~/^#/ && NF>0) {print}' "$infile" > "$outfile"
done
또는
for file in *LC.fa
do
infile="${file%.*}.fmt7"
outfile="${file%.*}.parsed.txt"
awk '$0~/^# V-\(D\)-J/ {print} ($0!~/^#/ && NF>0) {print;exit}' "$infile" > "$outfile"
done
각기.
ls
루프는 의 출력이 구문 분석됨에 따라 더욱 강력해집니다. 즉,적극 권장하지 않음.
awk
명령에 대한 몇 가지 설명
awk
조건이 "주" 프로그램 공간에 있고 해당 규칙이 에 있는 "조건부 규칙" 구문에 적용됩니다 { ... }
.
첫 번째 예에서는, 조건과 규칙이 있습니다.
- 역참조를 통해 행이
$0
정규식과 일치하는 경우^# V-\(D\)-J
, 즉^
문자열( )로 시작합니다.V-(D)-J
- 또는(
||
) 물론아니요#
($0!~/^#/
표현식) 으로 시작그리고또한 비어 있지 않습니다. 즉, "필드 구분 기호" 변수로 정의된 필드가 하나 이상 있습니다(NF>0
- 단순으로 단축할 수도 있음)(기본값은 공백)NF
print
그러면 줄이 있습니다 .
이렇게 하면 헤더와 연속된 데이터 줄이 인쇄됩니다.
두 번째 예에서는, 연관 규칙에는 두 가지 조건이 있습니다.
- 행이 문자열로 시작하면 해당 행입니다
# V-(D)-J
.print
- 만약 라인아니요로 시작
#
하고 비어 있지 않은print
다음 즉시 파일 처리를exit
종료합니다 .awk
이런 식으로 "헤더"가 인쇄되지만 첫 번째 "데이터" 줄을 만나 인쇄되면 실행을 중지하고 각 파일의 첫 번째 데이터 줄과 함께 헤더만 인쇄합니다.
답변2
for 루프를 설정하고 sed를 호출하여 구문 분석된 파일을 생성할 수 있습니다.
for f in *LC.fa; do
if=${f%.*}.fmt
of=${f%.*}.parsed.txt
sed -e '
8N;9q
6N;/\n./q;d
' < "$if" > "$of"
done