【问题标题】:Compare 2 csv files and merge common field records into 1st file比较 2 个 csv 文件并将常用字段记录合并到第一个文件中
【发布时间】:2019-12-08 19:10:48
【问题描述】:

我正在尝试编写一个 shell 脚本/bash 命令,它将使用 csv 中的第三个字段(以 91 开头)比较 2 个 csv 文件,第一个文件有数百万条记录,第二个文件,一个较小的文件有数千条数据.如果通过比较第一个文件中的第三个字段在第二个文件中找到匹配项,则第二个文件中的匹配记录(较小的一个)应替换第一个文件中的记录或创建一个第三个文件,该文件将具有来自第二个文件的匹配记录替换第一个文件中的匹配记录。

我正在尝试这样的事情,但没有给出所需的输出:grep -v -f file2.csv file1.csv

CSV 文件 1:

0,104673081,91623178295,false,2019-03-21 03:31:04,2019-03-24 13:18:03
0,104673361,91678296502,false,2019-03-21 03:35:35,2019-05-22 21:55:50
0,104679130,**91661560977**,false,2019-03-21 03:36:37,2019-03-21 03:37:00
0,104674082,91691721155,false,2019-03-21 03:49:07,2019-06-21 08:13:00

CSV 文件 2:

0,104673063,91623178427,false,2019-03-21 03:31:04,2019-03-24 13:18:03
0,104673321,91678296913,false,2019-03-21 03:35:35,2019-05-22 21:55:50
0,104679111,**91661560977**,false,2019-03-21 03:36:37,2019-03-21 04:34:00

预期输出:

文件 1(通过比较第三个字段来匹配第二个文件的记录,即第二个文件中的 91661560977 已经替换了第一个文件中的记录)

0,104673081,91623178295,false,2019-03-21 03:31:04,2019-03-24 13:18:03
0,104673361,91678296502,false,2019-03-21 03:35:35,2019-05-22 21:55:50
0,104679111,**91661560977**,false,2019-03-21 03:36:37,2019-03-21 04:34:00
0,104674082,91691721155,false,2019-03-21 03:49:07,2019-06-21 08:13:00

【问题讨论】:

  • 请在您的问题中添加两件事。 1- 代码标签中的两个输入文件的示例。 2- 代码标签中的预期输出示例,一旦完成,请在此处的评论部分告诉我们。
  • 嗨,Ravinder,如前所述添加了详细信息

标签: bash shell csv awk


【解决方案1】:

可能是这样的?:

$ awk -F, 'NR==FNR{a[$3]=$0;next}$3 in a{$0=a[$3]}1' file2 file1

输出:

0,104673081,91623178295,false,2019-03-21 03:31:04,2019-03-24 13:18:03
0,104673361,91678296502,false,2019-03-21 03:35:35,2019-05-22 21:55:50
0,104679111,**91661560977**,false,2019-03-21 03:36:37,2019-03-21 04:34:00
0,104674082,91691721155,false,2019-03-21 03:49:07,2019-06-21 08:13:00

解释:

$ awk -F, '         # comma delimiter
NR==FNR {           # process first file, ie. file2
    a[$3]=$0        # hash record, $3 is the key NOTICE NEEDS TO BE UNIQUE
    next            # process next record
}
$3 in a {           # process second file, if matching $3 found in both files
    $0=a[$3]        # replace record with the one from file2
}1' file2 file1     # output. mind the file order to hash the smaller fie

如果您还想转储 file2 的其余部分:

$ awk -F, 'NR==FNR{a[$3]=$0;next}$3 in a{$0=a[$3];delete a[$3]}1; END{for(i in a)print a[i]}' file2 file1

【讨论】:

  • 好的,但是我们不是也将文件 2 中的不匹配记录合并到文件 1 中吗?
  • 我们是否也没有将文件 2 中的不匹配记录合并到文件 1 中 该脚本仅替换 file1 中的行(同时将这些行输出到标准输出)来自file2 的那些行与$3 相等,因此我们不会将文件2 中的不匹配记录合并到文件1。我没有看到这样的要求,预期的输出也没有反映这一点。
  • @JamesBrown,是的,我支持你,先生,这是稍后添加的。
  • 易于实现,您:在使用时从a[]END{} print 其余a[] 中删除元素
  • 我自己睡了半天。而且它只有2300(为什么晚上还这么年轻,昨晚尝试修复一个gawk |&c-program直到0500并且没有时间睡觉)。也许不仅仅是 deleteing 使用过的元素,而是从 a[] 将其复制到另一个数组 b[]delete 并检查两者是否存在。然后在END 中从a[] 打印。我会尽量避免sorting 大文件。
猜你喜欢
  • 1970-01-01
  • 2015-05-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-09-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多