使用两列比较三个文件,并使用awk / sed在每个文件中打印唯一条目

时间:2018-02-19 22:56:25

标签: bash awk sed overlap

我有三个文件格式如下:

$ cat a.bed 
chr1    6   6   aa
chr1    8   8   bb
chr2    22  22  aa
chr3    24  24  bb

$ cat b.bed 
chr1    12  12  cc
chr1    6   6   dd
chr5    14  14  cc

$ cat c.bed 
chr1    8   8   ss
chr4    11  11  dd
chr1    6   6   aa

我想使用前两列比较这些文件并打印每行的信息,无论它是存在于一个文件还是多个文件中,如:

chr1    6   6   aa  3   a.bed,b.bed,c.bed
chr1    8   8   bb  2   a.bed,c.bed
chr2    22  22  aa  1   a.bed
chr3    24  24  bb  1   a.bed
chr1    12  12  cc  1   b.bed
chr5    14  14  cc  1   b.bed
chr4    11  11  dd  1   c.bed

其中第5列给出了它所存在的文件数,第6列给出了文件的名称。

2 个答案:

答案 0 :(得分:0)

尝试这四行gawk(似乎没有在awk中工作):

gawk '{print $0, FILENAME}' a.bed > abc.bed
gawk '{print $0, FILENAME}' b.bed >> abc.bed
gawk '{print $0, FILENAME}' c.bed >> abc.bed
gawk '{f = $5;k=$1 " " $2 " " $3 " " $4;if(k in a){a[k] = a[k] "," f}else{a[k] = f};c[k]++};END{for(k in a){print k, c[k], a[k]}}' abc.bed

单个char变量简洁: f - 文件名, k - 键,即数据, a - 一系列键, c - 一系列密钥计数。

呃,如果我正确阅读,你的输入和输出数据样本不匹配,例如只有2' chr1 6 6 aa'不是3。

答案 1 :(得分:0)

awk救援!

$ awk '{a[$1,$2]=(($1,$2) in a?a[$1,$2]",":$0 OFS)FILENAME}
   END{for(k in a) print a[k]}' {a,b,c}.bed

结果虽然不会有相同的顺序。

<强>解释

  

x=c?a:b是三元运算符,根据c的值将x设置为a或b(类似于if-then-else)。在这里,我们通过附加($1,$2)(如果已经存在)或设置为当前行(再次附加FILENAME)来为关键FILENAME指定地图值。在END块中,只需遍历此映射,然后打印值。