使用 awk 在包含跨两个文件的字段内定界符的单个字段中的字符串中搜索?

Searching within strings in a single field containing an in-field delimiter across two files using awk?

我有两个文件。

file01.tab:

Q86IC9   PGEN_.00g000010
P04177   PGEN_.00g000020
Q8L840   PGEN_.00g000050
Q61043   PGEN_.00g000060
A1E2V0   PGEN_.00g000080
P34456   PGEN_.00g000090
P34457   PGEN_.00g000120
O00463   PGEN_.00g000210
Q00945   PGEN_.00g000230
Q5SWK7   PGEN_.00g000240

file02.tab:

Q86IC9;Q552T5                                                omt5
P04177                                                       Th
Q8L840;O04092;Q9FT71                                         RECQL4A
Q61043;A0A1Y7VJL5;B2RQ73;B7ZMZ9;E9Q488;E9Q4S3;Q674R4;Q6ZPM7  Nin
A1E2V0                                                       BIRC3
P34456                                                       Uncharacterized
P34457                                                       uncharacterized
O00463;B4DIS9;B4E0A2;Q6FHY1                                  TRAF5
Q00945                                                       RING
Q5SWK7;Q8BXX5;Q9CXG1                                         Rnf145

我想使用 file01.tab 中的第一列与 file02.tab 中的第一列连接。我可以用 grep 来做到这一点,但我需要按以下方式格式化输出:

PGEN_.00g000010 Q86IC9;Q552T5           omt5
PGEN_.00g000020 P04177                  Th
QPGEN_.00g000050 Q8L840;O04092;Q9FT71   RECQL4A

我已经非常接近使用以下 awk 代码的成功:

awk 'NR==FNR{a[]=[=13=]; next} ( in a){print ,a[]}' file02.tab file01.tab

单行将产生以下结果:

PGEN_.00g000020 P04177  Th
PGEN_.00g000080 A1E2V0  BIRC3
PGEN_.00g000090 P34456  Uncharacterized
PGEN_.00g000120 P34457  uncharacterized
PGEN_.00g000230 Q00945  RING
PGEN_.00g000280 Q8ZXT3  protein
PGEN_.00g000300 Q5REG4  DTX3
PGEN_.00g000450 A0JMR6  mysm1
PGEN_.00g000490 Q7D513  Hercynine
PGEN_.00g000530 A6H769  RPS7

该代码 file02.tab </code> 中找到匹配项,其中存在字段内分号分隔符。它只会找到在 <code>.

中只有一个条目的匹配项

显然,grep 可以处理使用两个输入文件的搜索,但我不知道如何格式化 grep 结果的输出,因为格式化需要来自两个输入文件的信息.

有什么方法可以用 awk 单行代码实现这一点,还是我应该编写一个小脚本来代替?

您可以在 awk

中尝试使用 split
awk 'NR==FNR{
        n=split(,s,";"); 
        for(i=1;i<=n;++i) a[s[i]]=[=10=]; 
        next;
    } ( in a){print ,a[];}
' file02.tab file01.tab

你明白了,

PGEN_.00g000010 Q86IC9;Q552T5                                                omt5
PGEN_.00g000020 P04177                                                       Th
PGEN_.00g000050 Q8L840;O04092;Q9FT71                                         RECQL4A
PGEN_.00g000060 Q61043;A0A1Y7VJL5;B2RQ73;B7ZMZ9;E9Q488;E9Q4S3;Q674R4;Q6ZPM7  Nin
PGEN_.00g000080 A1E2V0                                                       BIRC3
PGEN_.00g000090 P34456                                                       Uncharacterized
PGEN_.00g000120 P34457                                                       uncharacterized
PGEN_.00g000210 O00463;B4DIS9;B4E0A2;Q6FHY1                                  TRAF5
PGEN_.00g000230 Q00945                                                       RING
PGEN_.00g000240 Q5SWK7;Q8BXX5;Q9CXG1                                         Rnf145

请您尝试以下操作:

awk -v FS='[;[:space:]]+' 'NR==FNR {a[]=; next}  in a {print a[], [=10=]}' file01.tab file02.tab

输出:

PGEN_.00g000010 Q86IC9;Q552T5                                                omt5
PGEN_.00g000020 P04177                                                       Th
PGEN_.00g000050 Q8L840;O04092;Q9FT71                                         RECQL4A
PGEN_.00g000060 Q61043;A0A1Y7VJL5;B2RQ73;B7ZMZ9;E9Q488;E9Q4S3;Q674R4;Q6ZPM7  Nin
PGEN_.00g000080 A1E2V0                                                       BIRC3
PGEN_.00g000090 P34456                                                       Uncharacterized
PGEN_.00g000120 P34457                                                       uncharacterized
PGEN_.00g000210 O00463;B4DIS9;B4E0A2;Q6FHY1                                  TRAF5
PGEN_.00g000230 Q00945                                                       RING
PGEN_.00g000240 Q5SWK7;Q8BXX5;Q9CXG1                                         Rnf145
  • FS='[;[:space:]]+' 按分号序列拆分行或 space 字符。
  • 为简单起见,我调换了文件的顺序。

如果这只是匹配分号分隔字符串中的第一个值,您还可以使用拆分并比较第一个值:

awk 'NR==FNR{split(,p,";");a[p[1]]=[=10=]; next} ( in a){print ,a[]}' file02.tab file01.tab

或删除所有从第一个分号开始的内容:

awk 'NR==FNR{x=;sub(/;.*/, "", x);a[x]=[=11=]; next} ( in a){print ,a[]}' file02.tab file01.tab

输出

PGEN_.00g000010 Q86IC9;Q552T5                                                omt5
PGEN_.00g000020 P04177                                                       Th
PGEN_.00g000050 Q8L840;O04092;Q9FT71                                         RECQL4A
PGEN_.00g000060 Q61043;A0A1Y7VJL5;B2RQ73;B7ZMZ9;E9Q488;E9Q4S3;Q674R4;Q6ZPM7  Nin
PGEN_.00g000080 A1E2V0                                                       BIRC3
PGEN_.00g000090 P34456                                                       Uncharacterized
PGEN_.00g000120 P34457                                                       uncharacterized
PGEN_.00g000210 O00463;B4DIS9;B4E0A2;Q6FHY1                                  TRAF5
PGEN_.00g000230 Q00945                                                       RING
PGEN_.00g000240 Q5SWK7;Q8BXX5;Q9CXG1                                         Rnf145