awk - 在匹配剩余列后添加一列

awk - 在匹配剩余列后添加一列

我有一个文件(文件1.txt),内容如下。

8145216 3377090 1.5
1405541 53595498 1.53637

我需要为上述文件中的前两列生成所有可能的组合。我使用php中讨论的程序答案生成所有组合。

找到组合后,我的文件如下。

3377090 8145216
1405541 8145216
1405541 3377090
53595498 8145216
53595498 3377090
53595498 1405541

在上面的文件中,我需要附加第三列值文件1.txt如果该值不存在于文件1.txt我需要附加 0 作为第三列。我试图得到的最终输出是,

3377090 8145216 1.5
1405541 8145216 0
1405541 3377090 0
53595498 8145216 0
53595498 3377090 0
53595498 1405541 1.53637

答案1

awk 'NR==FNR{a[$1>=$2?$1SUBSEP$2:$2SUBSEP$1]=$3;next};
{k=$1>=$2?$1SUBSEP$2:$2SUBSEP$1; print $0, k in a?a[k]:0}' file1.txt file2.txt
3377090 8145216 1.5
1405541 8145216 0
1405541 3377090 0
53595498 8145216 0
53595498 3377090 0
53595498 1405541 1.53637

答案2

就我个人而言,我会在原始文件中使用 Awk 完成全部工作,而不是一半使用 PHP,一半使用 Awk 或 Perl。给定文件1.txt如上所述,以下将产生所需的输出:

{
    Vals[$1]++;
    Vals[$2]++;
    Third_col[$1, $2] = Third_col[$2, $1] = $3;
}
END{
    for (i in Vals) {
        for (j in Vals) { 
            if (i == j || (i SUBSEP j in printed)) { continue } 
            Third_col_val = (i SUBSEP j in Third_col) ? Third_col[i, j] : 0; 
            print i, j, Third_col_val; 
            printed[j, i]++; 
            printed[i, j]++ 
        } 
    } 
}

请注意,这需要 O(n 2 ) 时间,因此对于非常大的列表(数百万行),它会变得很慢并且占用大量内存。

答案3

另一个awk解决方案:

$ awk 'FNR==NR{a[$1,$2]=$3;next}
    {print $0,a[$1,$2]?a[$1,$2]:a[$2,$1]?a[$2,$1]:0}
' file1 file2
3377090 8145216 1.5
1405541 8145216 0
1405541 3377090 0
53595498 8145216 0
53595498 3377090 0
53595498 1405541 1.53637

相关内容