在Linux中,合并两个CSV文件需要匹配行并添加新列。

4

我正在使用Java开发一个应用程序,但是为此我需要按照一定顺序的csv文件。我对Linux并不是很了解,但想知道是否有某种方法可以将csv文件合并为所需格式。

我有两个包含数十万条记录的csv文件。下面是一个样例:

name,Direction,Date
abc,sent,Jan 21 2014 02:06 
xyz,sent,Nov 21 2014 01:09
pqr,sent,Oct 21 2014 03:06  

并且

name,Direction,Date
abc,received,Jan 22 2014 02:06
xyz,received,Nov 22 2014 02:06

所以,这个第二个csv文件将包含文件1的某些记录。我需要一个像这样的新csv:
name,Direction,Date,currentDirection,receivedDate
abc,sent,Jan 21 2014 02:06,received,Jan 22 2014 02:06
xyz,sent,Nov 21 2014 01:09,received,Nov 22 2014 02:06
pqr,sent,Oct 21 2014 03:06

需要根据第一列中的匹配数据添加列(第四列和第五列),如果第二个文件中没有匹配数据,则这些列应为空,就像上面那样。

那么在linux中是否有Bash命令可以实现这一点?

2个回答

4

awk 可能适合你的需求:

kent$  awk -F, -v OFS="," 
       'BEGIN{print "name,Direction,Date,currentDirection,receivedDate"}
        NR==FNR&&NR>1{a[$1]=$0;next}
        FNR>1{printf "%s%s\n",$0,($1 in a?FS a[$1]:"")}' 2.csv 1.csv
name,Direction,Date,currentDirection,receivedDate
abc,sent,Jan 21 2014 02:06,abc,received,Jan 22 2014 02:06
xyz,sent,Nov 21 2014 01:09,xyz,received,Nov 22 2014 02:06
pqr,sent,Oct 21 2014 03:06

更新

kent$  awk -F, -v OFS="," 'BEGIN{print "name,Direction,Date,currentDirection,receivedDate"}
        NR==FNR&&NR>1{a[$1]=$2 FS $3;next}
        FNR>1{printf "%s%s\n",$0,($1 in a?FS a[$1]:"")}' 2.csv 1.csv 
name,Direction,Date,currentDirection,receivedDate
abc,sent,Jan 21 2014 02:06,received,Jan 22 2014 02:06
xyz,sent,Nov 21 2014 01:09,received,Nov 22 2014 02:06
pqr,sent,Oct 21 2014 03:06

肯特 - 它的工作不如预期。输出如下:名称,方向,日期,当前方向,接收日期 ABC,发送,2014年1月21日02:06,ABC,接收,2014年1月22日02:06 - ani0710
第一列重复了,而且列也没有按照所需的格式排列。 - ani0710
在你的回答中,你会发现名称重复了两次,例如abc出现了两次。我需要的是名称不应该重复...它必须是abc,sent,jan 21 2014,received,jan 22 2014 - ani0710
@ani0710 好的,我明白了,没有仔细检查你的输出,是我的错,我会尽快更新答案。 - Kent
那就是我需要的。非常感谢,Kent :) - ani0710
显示剩余2条评论

3
您可以使用 join 命令来完成此操作。第一个文件是 1.csv,第二个文件是 2.csv
join -1 1 -2 1 -t, -a 1  1.csv 2.csv | sed "s/Direction,Date/currentDirection,receivedDate/2"

输出:

name,Direction,Date,currentDirection,receivedDate
abc,sent,Jan 21 2014 02:06,received,Jan 22 2014 02:06
xyz,sent,Nov 21 2014 01:09,received,Nov 22 2014 02:06
pqr,sent,Oct 21 2014 03:06 

解释:

您想要在两个文件的第一个字段上进行连接,因此使用-1 1 -2 1

您想要使用逗号分隔符,因此使用-t,

您想要显示文件1中所有未匹配的记录,因此使用-a 1,如果需要,还可以添加-a 2

sed命令中的/2表示替换第二次出现的内容。


太好了,它完美地运行了!但我需要的是第4列和第5列的不同名称。您能否根据这个需求修改您的命令? - ani0710
你能进一步解释一下,如果我使用-a 2会发生什么吗?我知道,-a 1用于显示文件1中所有不匹配的记录。那么-a 2会做什么?它会显示文件2的所有记录吗?那么文件1的记录呢? - ani0710
这是-a选项的作用:打印来自文件FILENUM的无法配对的行,其中FILENUM为1或2,对应于FILE1或FILE2。 - jftuga
运行 join --help 以获取更多选项。 - jftuga
谢谢您的解释。您给出的命令简短易懂 :) - ani0710

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接