您好我有以下格式的2个csv,(基本上是电子邮件列表和我们通过该发件人通过电子邮件发送的次数):
file1.csv
Email,Value
email1@email.com,2
email2@email.com,4
email3@email.com,1
email4@email.com,6
file2.csv
Email,Value
email1@email.com,3
email2@email.com,6
email3@email.com,8
email4@email.com,2
每个表中的值可能不同,我想要做的是将结果输出到一个新的CSV,如下所示:
file3.csv
Email,Value1,Value2
email1@email.com,2,3
email2@email.com,4,6
email3@email.com,1,8
email4@email.com,6,2
我从其他地方获得了一个bash
脚本,它完成了部分工作,但它没有列出我正在寻找的结果。
任何人都可以帮助使用bash脚本吗?
#!/bin/bash
join -t"," -1 1 -2 1 -a1 file1.csv file2.csv | awk -F, ' BEGIN {
print "Email,Value"
} NF > 3 {
if ( $3 != $5 )
print $1, $3, $5
if ( $2 != $4 )
print $1, $2, $4
} ' OFS=,
这是我通过使用以下内容获得的结果:
awk 'BEGIN{FS=OFS=","; printf "Name,Value1,Value2\n"}NR >1 &&
FNR==NR{map[$1]=$2; next}$1 in map{$(NF+1)=map[$1]; print}' file2.csv
file1.csv
结果:
Name,Value1,Value2
,3ail1@email.com,2
,6ail2@email.com,4
,8ail3@email.com,1
Email4@email.com,6,2
答案 0 :(得分:1)
使用join
程序
join -t, -o0,1.2,2.2 -a1 -a2 <(sort <file1.csv) <(sort <file2.csv)
否则,如果文件已经排序并包含相同的条目 与bash builtins
while
IFS=, read -u3 em1 val1
IFS=, read -u4 em2 val2
[[ -n $em1 ]] && [[ -n $em2 ]]
do
if [[ $em1 = $em2 ]]; then
echo "$em1,$val1,$val2"
else
echo "ERROR: $em1 <> $em2"
fi
done 3<file1.csv 4<file2.csv
答案 1 :(得分:1)
使用Awk
,直接!
awk 'BEGIN{FS=OFS=","; printf "Name,Value1,Value2\n"}NR >1 && FNR==NR{map[$1]=$2; next}$1 in map{$(NF+1)=map[$1]; print}' file2 file1
产生
Name,Value1,Value2
email1@email.com,2,3
email2@email.com,4,6
email3@email.com,1,8
email4@email.com,6,2
将输入和输出字段分隔符设置为在处理输入行之前执行的,
子句中的BEGIN
以及所需的 final 标头信息。在这种情况下,部件FNR==NR
按顺序file2
运行第一个文件,创建一个哈希映射,索引设置为$1
,值设置为$2
然后在file1
上为散列索引值属于$1
的那些行创建一个新字段$(NF+1)
,表示新值的最后一个字段+ 1
并打印所形成的结果。
答案 2 :(得分:1)
如果你想保留订单
awk
救援!
$ awk 'BEGIN {FS=OFS=","}
NR==FNR {a[$1]=$2; next}
FNR==1 {print $1,$2"1",a[$1]"2"; next}
{print $1,$2,a[$1]}' file2 file1
Email,Value1,Value2
email1@email.com,2,3
email2@email.com,4,6
email3@email.com,1,8
email4@email.com,6,2
记下文件的顺序......
答案 3 :(得分:0)
构建一个循环,遍历第一个文件中的每一行。
在该循环中,构建另一个循环,将第二个文件的每一行与第一个文件的当前行进行比较。
将匹配项写入新文件。