我有两个CSV文件,我想使用AWK比较它们并生成一个新文件。
file1.csv:
"no","loc"
"abc121","C:/pro/in"
"abc122","C:/pro/abc"
"abc123","C:/pro/xyz"
"abc124","C:/pro/in"
file2.csv:
"no","loc"
"abc121","C:/pro/in"
"abc122","C:/pro/abc"
"abc125","C:/pro/xyz"
"abc126","C:/pro/in"
output.csv:
"file1","file2","Diff"
"abc121","abc121","Match"
"abc122","abc122","Match"
"abc123","","Unmatch"
"abc124","","Unmatch"
"","abc125","Unmatch"
"","abc126","Unmatch"
答案 0 :(得分:0)
我没有单独使用awk
,但如果我理解你正确要求的要点,我认为这个长篇单行应该这样做......
join -t, -a 1 -a 2 -o 1.1 2.1 1.2 2.2 file1.csv file2.csv | awk -F, '{ if ( $3 == $4 ) var = "\"Match\""; else var = "\"Unmatch\"" ; print $1","$2","var }' | sed -e '1d' -e 's/^,/"",/' -e 's/,$/,"" /' -e 's/,,/,"",/g'
描述:
join
部分获取两个CSV文件,将它们连接到第一列(默认行为join
)并输出所有四个字段(-o 1.1 2.1 1.2 2.2
),确保包含行这两个文件都不匹配(-a 1 -a 2
)。 awk
部分获取该输出,并将第3和第4列的组合替换为"Match"
或"Unmatch"
,具体取决于它们是否实际匹配。我必须根据你的例子对这种行为做出假设。 sed
部分从输出(-e '1d'
)中删除“no”,“loc”标头,并用开 - 关引号(-e 's/^,/"",/' -e 's/,$/,""/' -e 's/,,/,"",/g'
)替换空字段。最后一部分可能对您没有必要。编辑: 正如三人指出的那样,如果两个初始文件未排序,则上述操作失败。这是一个更新的命令来解决这个问题。它将标题行放入并对每个文件进行排序,然后再将它们传递给加入...
join -t, -a 1 -a 2 -o 1.1 2.1 1.2 2.2 <( sed 1d file1.csv | sort ) <( sed 1d file2.csv | sort ) | awk -F, '{ if ( $3 == $4 ) var = "\"Match\""; else var = "\"Unmatch\"" ; print $1","$2","var }' | sed -e 's/^,/"",/' -e 's/,$/,""/' -e 's/,,/,"",/g'
答案 1 :(得分:0)
awk
的一种方式:
BEGIN {
FS = ","
}
NR>1 && NR==FNR {
a[$1] = $2
next
}
FNR>1 {
print ($1 in a) ? $1 FS $1 FS "Match" : "\"\"" FS $1 FS "Unmatch"
delete a[$1]
}
END {
for (x in a) {
print x FS "\"\"" FS "Unmatch"
}
}
$ awk -f script.awk file1.csv file2.csv
"abc121","abc121",Match
"abc122","abc122",Match
"","abc125",Unmatch
"","abc126",Unmatch
"abc124","",Unmatch
"abc123","",Unmatch