使用键值连接两个csv文件

时间:2014-09-16 17:49:47

标签: bash csv awk

我有两个csv文件,我想使用键值(城市列)加入它们。

一个csv文件,d01.csv有这种形式,

Barcelona, 19.5, 29.5
Tarragona, 20.4, 31.5 
Girona, 17.2, 32.5
Lleida, 16.5, 33.5 
Vic, 17.5, 31.4

另一个,d02.csv,具有下一个结构,

City, Data, TMax, TMin
Barcelona, 20140916, 19.9, 28.5
Tarragona, 20140916, 21.4, 30.5  
Lleida, 20140916, 17.5, 32.5 
Tortosa, 20140916, 20.5, 30.4

我需要一个新的csv文件,其中一列城市显示在2个csv文件中。

City, Tmin, Tmax, Date, Tmin1, Tmax1
Barcelona, 19.5, 29.5, 20140916, 19.9, 28.5
Tarragona, 20.4, 31.5, 20140916, 21.4, 30.5
Girona, 17.2, 32.5, 20140916, 17.5, 32.5
Lleida, 16.5, 33.5, 20140916, 20.5, 30.4

我尝试用

做到这一点
join -j 2 -t ',' d01.csv d02.csv | awk -F "," '{print $1, $2, $3, $4, $5} > d03.csv

但它不完整......如何订购键值?

3 个答案:

答案 0 :(得分:10)

以下是如何在bash中使用join:

{
  echo "City, Tmin, Tmax, Date, Tmin1, Tmax1"
  join -t, <(sort d01.csv) <(sed 1d d02.csv | sort)
} > d03.csv
cat d03.csv
City, Tmin, Tmax, Date, Tmin1, Tmax1
Barcelona, 19.5, 29.5, 20140916, 19.9, 28.5
Lleida, 16.5, 33.5 , 20140916, 17.5, 32.5 
Tarragona, 20.4, 31.5 , 20140916, 21.4, 30.5  

请注意,join仅输出两个文件中密钥存在的记录。要获取所有这些,请指定您希望从两个文件中丢失记录,指定所需的字段,并为缺少的字段提供默认值:

join -t, -a1 -a2 -o 0,1.2,1.3,2.2,2.3,2.4 -e '?' <(sort d01.csv) <(sed 1d d02.csv | sort)
Barcelona, 19.5, 29.5, 20140916, 19.9, 28.5
Girona, 17.2, 32.5,?,?,?
Lleida, 16.5, 33.5 , 20140916, 17.5, 32.5 
Tarragona, 20.4, 31.5 , 20140916, 21.4, 30.5  
Tortosa,?,?, 20140916, 20.5, 30.4
Vic, 17.5, 31.4,?,?,?

答案 1 :(得分:1)

我建议CSV Cruncher将CSV文件作为SQL表,然后允许SQL查询,从而产生另一个CSV文件。

示例:

crunch input.csv output.csv \
   "SELECT AVG(duration) AS durAvg FROM (SELECT * FROM indata ORDER BY duration LIMIT 2 OFFSET 6)"

该工具需要Java 5或更高版本。

一些优点:

  • 您真的得到了CSV支持,而不仅仅是“我们假设数据是正确的”。
  • 您可以加入多个密钥。
  • 比基于join的解决方案更易于使用和理解。
  • 您可以组合2个以上的CSV文件。
  • 您可以通过SQL表达式加入 - 值不必相同。

免责声明:我写了这个工具。未知的项目状态 - 谷歌代码已关闭,我没有尽快转移它。如果有人有兴趣,我可能会看看它。

答案 2 :(得分:0)

awk可能会:

awk 'FNR==NR {a[$1]=$2FS$3FS$4;next} $1 in a {print $0,a[$1]}' OFS=", " d02,csv d01csv
Barcelona, 19.5, 29.5, 20140916, 19.9, 28.5
Tarragona, 20.4, 31.5 , 20140916, 21.4, 30.5
Lleida, 16.5, 33.5 , 20140916, 17.5, 32.5