我有两个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"柱
答案 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价值需要额外的工作。
由于某些字段值使用嵌入式分隔符双引号,而join
和awk
等标准实用程序处理不当,因此额外的工作变得复杂。
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