파일 A에는 모든 데이터가 포함되어 있고 다른 파일 B에는 ID만 포함되어 있는 두 개의 파일이 있습니다. 내가 원하는 것은 파일 B를 파일 A와 비교하고 해당 ID에 있는 데이터를 검색하는 것입니다. 저는 수세 리눅스를 사용하고 있습니다.
파일 A
C 02020 Two-component system [PATH:aap02020]
D NT05HA_1798 sensor protein CpxA
D NT05HA_1797 CpxR K07662 cpxR
C 02030 *Bacterial chemotaxis* [PATH:aap02030]
D NT05HA_0919 maltose-binding periplasmic protein
D NT05HA_0918 maltose-binding periplasmic protein
C 03070 *Bacterial secretion system* [PATH:aap03070]
D NT05HA_1309 protein-export membrane protein SecD
D NT05HA_1310 protein-export membrane protein SecF
D NT05HA_1819 preprotein translocase subunit SecE
D NT05HA_1287 protein-export membrane protein
C 02060 Phosphotransferase system (PTS) [PATH:aap02060]
D NT05HA_0618 phosphoenolpyruvate-protein
D NT05HA_0617 phosphocarrier protein HPr
D NT05HA_0619 pts system
문서 B
Bacterial chemotaxis
Bacterial secretion system
원하는 출력:
C 02030 *Bacterial chemotaxis* [PATH:aap02030]
D NT05HA_0919 maltose-binding periplasmic protein
D NT05HA_0918 maltose-binding periplasmic protein
C 03070 *Bacterial secretion system* [PATH:aap03070]
D NT05HA_1309 protein-export membrane protein SecD
D NT05HA_1310 protein-export membrane protein SecF
D NT05HA_1819 preprotein translocase subunit SecE
D NT05HA_1287 protein-export membrane protein
답변1
당신이 사용할 수있는 awk
:
awk 'NR==FNR{ # On the first file,
a[$0]; # store the content in the array a
next
}
{ # On the second file,
for(i in a) # for all element in the array a,
if(index($0,i)) { # check if there is match in the current record
print "C" $0 # in that case print it with the record separator
next
}
}' fileB RS='\nC' fileA
C 02030 *Bacterial chemotaxis* [PATH:aap02030]
D NT05HA_0919 maltose-binding periplasmic protein
D NT05HA_0918 maltose-binding periplasmic protein
C 03070 *Bacterial secretion system* [PATH:aap03070]
D NT05HA_1309 protein-export membrane protein SecD
D NT05HA_1310 protein-export membrane protein SecF
D NT05HA_1819 preprotein translocase subunit SecE
D NT05HA_1287 protein-export membrane protein
답변2
C <word>
와 사이의 부분을 정확히 일치시키려는 경우 [PATH:...]
(그리고 *
샘플의 부분은 실제 데이터의 일부가 아니라 강조를 위한 것일 뿐이라고 가정) 다음을 수행할 수 있습니다.
awk '
!start {all_strings[$0]; next}
/^C/ {
key = $0
# strip the leading C <word>:
sub(/^C[[:blank:]]+[^[:blank:]]+[[:blank:]]*/, "", key)
# strip the trailing [...]:
sub(/[[:blank:]]*\[[^]]*][[:blank:]]*$/, "", key)
selected = key in all_strings
}
selected' fileB start=1 fileA
신뢰성을 높이는 것 외에도(예: Bacterial secretion
하나의 레코드만 일치 Bacterial secretion
, 일치하지 않음 Bacterial secretion system
) 파일을 한 번만 읽고 일치는 많은 하위 문자열 검색이나 정규 표현식 일치가 아닌 해시 테이블 조회이므로 매우 효율적입니다.
답변3
루프를 사용하면 쓰러질 것이라고 확신하지만 그래도... 여기에 한 가지 접근 방식이 있습니다.
#!/bin/bash
while read -r line; do
sed -n "/$line/,/^C/p" fileA | sed '$d'
done < fileB
예:
./bacteria.sh
C 02030 *Bacterial chemotaxis* [PATH:aap02030]
D NT05HA_0919 maltose-binding periplasmic protein
D NT05HA_0918 maltose-binding periplasmic protein
C 03070 *Bacterial secretion system* [PATH:aap03070]
D NT05HA_1309 protein-export membrane protein SecD
D NT05HA_1310 protein-export membrane protein SecF
D NT05HA_1819 preprotein translocase subunit SecE
D NT05HA_1287 protein-export membrane protein
샘플 파일은 어디에 있나요 fileA
?fileB
정규식 분석:
sed -n "/$line/,/^C/p" fileA | sed '$d'
$line
문자로 시작하는 줄과 다음 줄 사이의 줄을 인쇄합니다 C
. 단, sed '$d'
마지막 줄은 "정지 표시" 역할만 하므로 제외( )합니다.
sed --version
sed (GNU sed) 4.2.2
bash --version
GNU bash, version 4.2.46(1)-release (x86_64-redhat-linux-gnu)
답변4
데이터는 새 줄로 시작하는 레코드 fileA
로 나뉩니다 . 각 레코드는 새 줄로 시작하는 inte 필드 C
로 나뉩니다 .D
행을 읽고 fileB
이를 사용하여 각 레코드의 첫 번째 필드를 쿼리해야 합니다 fileA
.
while read -r query; do
awk -vq="$query" 'BEGIN { RS="^C|\nC"; FS=OFS="\nD" } $1 ~ q {print "C" $0}' fileA
done <fileB
줄 시작 부분 어디든 RS
일치하도록 레코드 구분 기호( )를 설정했습니다.C
또는줄 바꿈 문자 뒤에 있으면 첫 번째 레코드의 어떤 항목도 올바르게 일치하지 않을 수 있습니다. awk
변수를 사용하여 q
파일에서 읽은 값을 보관하고 각 레코드의 첫 번째 필드를 해당 값과 일치시킵니다.
결과:
C 02030 *Bacterial chemotaxis* [PATH:aap02030]
D NT05HA_0919 maltose-binding periplasmic protein
D NT05HA_0918 maltose-binding periplasmic protein
C 03070 *Bacterial secretion system* [PATH:aap03070]
D NT05HA_1309 protein-export membrane protein SecD
D NT05HA_1310 protein-export membrane protein SecF
D NT05HA_1819 preprotein translocase subunit SecE
D NT05HA_1287 protein-export membrane protein