awk 比较两个文件,提取,输出到第三个文件

awk 比较两个文件,提取,输出到第三个文件

我用 Python 写了一个脚本,但它的速度不够快,无法完成这项工作。我认为逐行处理会更好。

我有两个文件,每个文件有两列,可能有数亿行(生物信息学)。这两个文件(文件 1、文件 2)类似,以制表符分隔,第一列包含字母和数字字符串,第二列包含整数。每个文件的标题都是name, 。count

我需要生成一个制表符分隔的文件,其中:每行的第一个条目来自列,但只有同时在和name中的名称,第二个条目是来自文件 1 的;第三个条目是来自的,保留标题。file1file2countnamecountnamefile2

经过大量阅读后,这是我的尝试:

awk '(NR == FNR) {
   n0[$1] = 0; 
   n1[$1] = 0; 
   next
 }     {
   if($1 in n0) {
     n2[$2] = 0
   }
 } END {
   for (i in n0) (j in n1) (k in n2) {
     print i,"\t",j,"\t",k
   } 
}' file1 file2

所以很明显我真的不知道创建数组要做什么(我不确定它们是否可以是二维的,所以我尝试使用三维)。

如果有人可以使用与上面相同的基本流语法来纠正 awk 脚本,那就太好了,非常感谢。

另外,要将其转换为可执行的 .sh 文件,应该怎么做?

从两个文件第一列的元素中(只有两个文件中都存在的元素)找到第一列中两个文件值的交集,然后

答案1

如果你的输入按第一列排序,那么效果会更好,因为你可以直接使用join命令:

$ cat foo 
a   1
b   2
c   3
d   4
$ cat bar
b   1
d   4
e   5
n   2
$ join -t $'\t' <(sort foo) <(sort bar)                                                                                                            
b   2   1
d   4   4

无论如何,我建议进行排序 - 如果没有排序,您可能会查看O(m*n)操作,但是如果进行排序,则O(m*log(m) + n*log(n) + min(m,n))进行操作 - 如果您优化方法而不是使用的语言,它应该可以节省您一段时间。

使用awk,你可以使用单个数组:

awk 'NR==FNR { n[$1] = $2; next } ($1 in n) {print $1, n[$1], $2}' foo bar

如果是的话,这也应该相当快$i in n

答案2

bash

假设file1

abc123 123456
def456 789123
ghi789 456789

file2

abc123 789123

这将输出file3

abc123 123456 789123
#!/bin/bash

while read line1; do
    var1=$(echo $line1 | tr '\t' '\n')
    while read line2; do
        var2=$(echo $line2 | tr '\t' '\n')
        if [ "${var1[0]}" == "${var2[0]}" ]; then
            printf "%s\t%s\t%s\n" "${var1[0]}" "${var1[1]}" "${var1[2]}"
        fi
    done < file2
done < file1

相关内容