如何使用shell / Python脚本组合CSV文件

时间:2017-01-14 04:40:10

标签: shell csv scripting

我有两个CSV文件

input.csv:

id,scenario,data1,data2,result
1,s1,300,400,"{s1,not added}"
2,s2,500,101,"{s2 added}"
3,s3,600,202,

output.csv

id,result
1,"{s1,added}"
3,"{s3,added}"

我想使用Shell / Python脚本组合这两个CSV,以便输出如下:

final_output.csv

id,scenario,data1,data2,result
1,s1,300,400,"{s1,added}"
2,s2,500,101,"{s2 added}"
3,s3,600,202,"{s3,added}"

条件:  1.加入两个csv的列是" id"柱

  1. 结果列数据(如果存在于output.csv中)然后覆盖该值。 如果它不存在则保持原样
  2. 你能帮帮忙吗?

2 个答案:

答案 0 :(得分:0)

这是一个仅使用bash内置的解决方案。将以下内容放在脚本文件中,使其可执行,然后在两个.csv文件所在的目录中运行它。

#!/bin/bash -ue

declare -A output_map

# Pattern representing 0 or more spacing characters
space="[[:space:]]*"

# Pattern for fields
field="$space([^,]*)$space"
last_field="$space(.*)$space"

# Build map of key/value in output.csv
while IFS= read -r line
do
  [[ "$line" =~ ^$field,$last_field$ ]] || continue
  key="${BASH_REMATCH[1]}"
  value="${BASH_REMATCH[2]}"
  output_map[$key]="$value"
done <"output.csv"

# Perform merge of the two files
while IFS= read -r line
do
  [[ "$line" =~ ^$field,$field,$field,$field,$last_field$ ]] || continue
  f1="${BASH_REMATCH[1]}"
  f2="${BASH_REMATCH[2]}"
  f3="${BASH_REMATCH[3]}"
  f4="${BASH_REMATCH[4]}"
  f5="${BASH_REMATCH[5]}"
  value="${output_map[$f1]-}"
  [[ -z "$value" ]] || f5="$value"
  echo "$f1,$f2,$f3,$f4,$f5"
done <"input.csv"

它不是特别紧凑,但如果您了解bash条件(=~运算符)中的模式匹配,则应该相对较清楚。

请注意,忽略与正确格式不匹配的行,并且带有标题的行不需要任何特殊处理。

如果您有任何疑问,请与我联系。

答案 1 :(得分:0)

\copy classified_advertisement from '/tmp/jangoads.csv' using delimiters ',' CSV HEADER ENCODING 'UTF8'; 将帮助您完成大部分工作 - 假设输入文件已经按连接字段排序 - 但要求有条件地保留左输入文件&#39; s价值需要额外的工作。

由于某些字段值使用嵌入式分隔符双引号,而joinawk等标准实用程序处理不当,因此额外的工作变得复杂。

sed辅助解决方案:

python

join -t, -a1 input.csv output.csv | python -c ' import csv, sys for row in csv.reader(sys.stdin): if(len(row)>5): row[4] = row[5] del row[5:] row[4] = "\"" + row[4] + "\"" print(",".join(row)) ' 辅助解决方案:

perl