【问题标题】:Row lookup in awk for a column between two files在 awk 中查找两个文件之间的列
【发布时间】:2016-06-08 14:22:45
【问题描述】:

我的 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]=$1;next} FNR==1 && f{print f;for(k in a) print a[k], a[k] in b; delete b}{b[$5]; 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

【问题讨论】:

  • 什么是二进制计数?有则为 1,无则为 0?
  • 另外,请注意 FILE1 中的 ** 具有误导性。我猜你希望它们加粗,但在代码块中它们看起来像原始的原始数据

标签: arrays awk lookup delimiter


【解决方案1】:

我认为您的计数已关闭或有一些未指定的情况

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

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

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

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

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

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

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

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

【讨论】:

  • 太棒了!非常感谢。抱歉,我尝试以粗体显示 id 并以星号代替。
  • 不错。你甚至可以说print $0, $0 in c ? c[$0] : 0
【解决方案2】:

让我们使用一些非智能方法。也就是说,将file1中的每一行与整个file2进行grep,得到grep的返回码:

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

【讨论】:

  • 我曾尝试 grepping,但由于文件很大,所以需要很长时间。
猜你喜欢
  • 2014-06-20
  • 1970-01-01
  • 2017-03-24
  • 1970-01-01
  • 2018-07-13
  • 1970-01-01
  • 1970-01-01
  • 2020-05-09
  • 1970-01-01
相关资源
最近更新 更多