我正在寻找一个UNIX shell解决方案,在两个文本文件之间执行等效的SQL MERGE
(或UPSERT
),其中一些字段是关键字段,其他字段可以更新/覆盖。
输入数据
这是我原来的数据:
AA;123;2016-01-31;1;456.53
AA;123;2016-02-01;1;75.24
AB;123;2000-08-08;1;756.1
AB;456;2016-07-07;2;8.24
CC;123;2007-07-21;15;10.34
CC;456;2009-09-09;9;943.65
CC;789;2005-04-23;1;1345.6
前三个字段(产品,客户和日期)是关键字段,最后两个字段(数量) 和金额)可以更新。
这是我的第二个文件,它只包含新的和更新的数据:
AA;123;2016-01-31;7;983.63
AA;123;2016-08-24;17;1687.73
CC;456;2009-09-09;11;2161.65
DD;91;2016-08-03;5;98.48
两个文件都已按以下方式排序:
sort -t';' -k1 -k2 -k3
第一个和第三个记录应覆盖现有行(更新数量和金额),而第二个和第三个记录应作为新行插入。
所需的输出
AA;123;2016-01-31;7;983.63
AA;123;2016-08-24;17;1687.73
AA;123;2016-02-01;1;75.24
AB;123;2000-08-08;1;756.1
AB;456;2016-07-07;2;8.24
CC;123;2007-07-21;15;10.34
CC;456;2009-09-09;11;2161.65
CC;789;2005-04-23;1;1345.6
DD;91;2016-08-03;5;98.48
我正在寻找使用sort
,uniq
或awk
和perl
的快速解决方案。
答案 0 :(得分:3)
当第1,第2,第3个字段的索引在file2中匹配时,您想要覆盖file1中的行。也就是说,file2具有"偏好"在file1上,如果file1中的一行在file2中没有它的对应关系,那么它就会打印出来。
如果是这样,那么打印所有两个文件,从file2开始,然后跳过那些重复file1-file2-file3的行呢?然后,管道对排序的输出进行排序:
Between DateSerial(Year(Date()), Month(Date()), 1) And Date()
答案 1 :(得分:2)
$ awk -F\; '{a[$1 FS $2 FS $3]= $4 FS $5} END {PROCINFO["sorted_in"]="@ind_str_asc"; for (i in a) print i FS a[i]}' file1 file2
AA;123;2016-01-31;7;983.63
AA;123;2016-02-01;1;75.24
AA;123;2016-08-24;17;1687.73
AB;123;2000-08-08;1;756.1
AB;456;2016-07-07;2;8.24
CC;123;2007-07-21;15;10.34
CC;456;2009-09-09;11;2161.65
CC;789;2005-04-23;1;1345.6
DD;91;2016-08-03;5;98.48
说明:
{
a[$1 FS $2 FS $3] = $4 FS $5 # write records overwriting where needed
}
END {
PROCINFO["sorted_in"]="@ind_str_asc" # for sort order
for (i in a) # output indexed records
print i FS a[i]
}