awk 中的行查找两个文件之间的列

Row lookup in awk for a column between two files

我有 FILE1 如下:

  CX    998900  998900  -   CX:998900:998900:**ENSG00000000001:E4**:AAAT:4.468:A1
  CX    998903  998903  -   CX:998903:998903:**ENSG00000000001:E4**:CAAT:6.600:A1
  CX    998889  998890  -   CX:998889:998890:**ENSG00000000003:E5**:TAAT:7.523:A1
  CX    998891  998891  -   CX:998891:998891:**ENSG00000000003:E5**:TAAT:7.518:A1
  CX    998881  998881  -   CX:998881:998881:**ENSG00000000002:E6**:AAAT:4.468:A1
  CX    998883  998883  -   CX:998883:998883:**ENSG00000000003:E6**:AAAT:5.784:A1
  CX    998880  998880  -   CX:998880:998880:**ENSG00000000003:E6**:AAAT:5.784:A1
  CX    998884  998884  -   CX:998884:998884:**ENSG00000000003:E6**:TAAT:6.202:A1

我将 FILE2 作为以粗体突出显示的 ID 列表:

 ENSG00000000001:E4
 ENSG00000000003:E5
 ENSG00000000002:E6  
 ENSG00000000003:E6
 ENSG00000000002:E5

我正在尝试使用以下 awk 命令从 FILE1 中的 FILE2 获取 id 的二进制计数

awk 'NR==FNR{a[NR]=;next} FNR==1 && f{print f;for(k in a) print a[k], a[k] in b; delete b}{b[]; f=FILENAME}END{print f; for(k in a) print a[k], a[k] in b; delete b}' FILE2 FILE1 

这样我得到

ENSG00000000001:E4  1
ENSG00000000003:E5  1
ENSG00000000002:E6  1  
ENSG00000000003:E6  1
ENSG00000000002:E5  0

我认为您的计数不对或存在某些未指定的情况

$ awk -F'**' -v OFS=':' 'NR==FNR{c[]++; next} 
                          in c{print ,c[]; next} 
                                {print ,0} ' file1 file2

ENSG00000000001:E4:2
ENSG00000000003:E5:2
ENSG00000000002:E6:1
ENSG00000000003:E6:3
ENSG00000000002:E5:0

哦,我看到的不是计数而是一个指标,因为将 c[]++ 替换为 c[]=1

如果**不是文件的一部分,你必须稍微改变它

$ awk -F':' 'NR==FNR{c[ FS ]=1; next} 
             [=11=] in c{print [=11=],c[[=11=]]; next} 
                    {print [=11=],0} ' file1 file2

ENSG00000000001:E4 1
ENSG00000000003:E5 1
ENSG00000000002:E6 1
ENSG00000000003:E6 1
ENSG00000000002:E5 0

这可以进一步简化,正如@fedorqui 评论的那样。

$ awk -F':' 'NR==FNR{c[ FS ];next} {print [=12=], [=12=] in c}' file1 file2

让我们使用一些非智能方法。也就是说,针对整个 file2 查找 file1 中的每一行,并获得 grep:

的 return 代码
while IFS= read -r line; do
    printf "%s\t%d\n" "$line" "$(grep -q "$line" f1 && echo 1 || echo 0)"
done < f2