根据最后一列中的值比较两个文件

根据最后一列中的值比较两个文件

我有两个文件,每个文件都有几列,并且行号不相等,我需要读取两个文件中的第三列并确保相同,然后比较两个文件中的第四列并获取最大数字并打印整行在第三个文件中。对于在其他文件中找不到的行,也将其作为最高编号

文件A

a b c 10
d e f 11
g h i 15
j k l 15
p l m 35

飞B

d e f 15
j k l 20
w x z 40

所需输出

文件C

a b c 10
d e f 15
g h i 15
j k l 20
p l m 35
w x z 40

答案1

像这样:

awk '$4>n[$3]{n[$3]=$4;l[$3]=$0}END{for(i in l)print l[i]}' file_a file_b > file_c

解释:如果第 4 列大于同一第 3 列(在n数组中)记住的最大值,则记住新的第 4 列和l该第 3 列的整行(在数组中)。最后打印所有记住的行。

答案2

$ cat fileA fileB | sort -k3,3 -k4,4nr | sort -k3,3 -u
a b c 10
d e f 15
g h i 15
j k l 20
p l m 35
w x z 40

这是一个由三个部分组成的管道:

  1. 连接fileAfileB.
  2. 对于第三列中的每个唯一值,根据第四列按数字降序对串联文件进行排序。这一步的结果是

    a b c 10
    d e f 15
    d e f 11
    g h i 15
    j k l 20
    j k l 15
    p l m 35
    w x z 40
    
  3. 再次对其进行排序,但删除重复项,并仅使用第三列作为排序键。由于这将保留第一个找到的排序键实例的行,但会丢弃具有重复排序键的行(第四列的值较低,这要归功于第一的sort),它会给我们想要的结果。

这种方法完全忽略前两列的内容。

答案3

如果您的 awk 解释器位于 /usr/bin/ 中:

cat doit.awk

#!/usr/bin/awk

NF!=4 {

    print "Field number must be 4" > "/dev/stderr";
    exit 1;
}

FILENAME=="file_a" {

    i++;
    numval_a[i]=$4;
    letters_a[i]=$1FS$2FS$3;
}

FILENAME=="file_b" {

    k++;
    numval_b[k]=$4;
    letters_b[k]=$1FS$2FS$3;
}

END {

    for(j=1; j<=i; j++) {

        if(letters_a[j]!=letters_b[j]) {

            print "Line missmatch!" > "/dev/stderr";
            exit 2;
        }

        if(numval_a[j]>numval_b[j])
            max=numval_a[j];
        else
            max=numval_b[j];

        print letters_a[j], max;
    }
}

awk -f doit.awk file_a file_b

a b c 10
d e f 15
g h i 20
j k l 25

相关内容