比较多个列并将结果附加到另一个文件中

时间:2015-01-20 10:09:34

标签: shell unix awk

我有两个文件file1file2,两个文件都有5 columns。 我想将first 4 columns file1file2进行比较。

如果它们相等,则需要比较5th column。如果5th column values不同,则需要将file1's 5th column打印为file2's 6th column

我使用下面的awk来比较两个不同文件中的两列,但是如果找到匹配项,如何比较多个列并将特定列附加到另一个文件中?

awk -F, 'NR==FNR{_1[$1]++;next}!_1[$1]'

文件1:

111,item1,garde1,wing1,maingroup
123,item3,grade5,wing10,topcat
132,item2,grade3,wing7,middlecat
134,item2,grade3,wing7,middlecat
177,item8,gradeA,wing11,lowcat

file2的:

111,item1,garde1,wing1,maingroup
123,item3,grade5,wing10,lowcat
132,item3,grade3,wing7,middlecat
126,item2,grade3,wing7,maingroup
177,item8,gradeA,wing11,lowcat

期望的输出:

123,item3,grade5,wing10,lowcat,topcat

2 个答案:

答案 0 :(得分:1)

Awk可以通过对索引进行排序来模拟多维数组。索引下面使用内置的SUBSEP变量作为分隔符连接:

 $ awk -F, -v OFS=, 'NR==FNR { a[$1,$2,$3,$4]=$5; next } a[$1,$2,$3,$4] && a[$1,$2,$3,$4] != $5 { print $0,a[$1,$2,$3,$4] }' file1.txt file2.txt

123,item3,grade5,wing10,lowcat,topcat

awk -F, -v OFS=,

将输入和输出分隔符都设置为,

NR==FNR { a[$1,$2,$3,$4]=$5; next }

从第一个文件创建一个关联数组,将每行的前四个字段与 第五。当使用以逗号分隔的值列表作为索引时,awk实际上将它们连接起来 使用内置SUBSEP变量的值作为分隔符。这是awk的方式 使用单个下标模拟多维数组。您可以将SUBSEP设置为您喜欢的任何值 但通常是默认值,即不太可能出现在数据中的非打印字符 精细。 (你也可以自己动手,比如a[$1 "|" $2 "|" $3 "|" $4], 假设您知道您的数据不包含竖线。)

a[$1,$2,$3,$4] && a[$1,$2,$3,$4] != $5 { print $0,a[$1,$2,$3,$4] }

到达这里,我们知道我们正在查看第二个文件。如果在前面找到了前四个字段 第一个文件,第一个文件中的$ 5与第二个文件中的$ 5不同,打印该行 从第二个文件开始,然后是第一个文件中的$ 5。 (我在这里假设第一个文件中没有5美元的值会被评估为false,例如0或空。)

答案 1 :(得分:0)

$ cat tst.awk
BEGIN { FS=OFS="," }
{ key = $0; sub("(,[^,]*){"NF-4"}$","",key) }
NR==FNR { file1[key] = $5; next }
(key in file1) && ($5 != file1[key]) {
    print $0, file1[key]
}

$ awk -f tst.awk file1 file2
123,item3,grade5,wing10,lowcat,topcat