映射多个 csv 文件中的字段并组合行

Posted

技术标签:

【中文标题】映射多个 csv 文件中的字段并组合行【英文标题】:Map fileds in multiple csv files and combine the rows 【发布时间】:2018-03-27 10:35:15 【问题描述】:

我的第一个 csv 文件中的数据是:

ID, name, city
1, John, NYC
2
3
4, Sam, SFO
5 

在第二个 csv 文件中

ID, name, city
3, Tim, STL
2, Daniel, BOS

第三个 csv 文件

ID, name, city
5, Eric, AST

我想要一个包含汇总数据的 csv 文件:

ID, name, city
1, John, NYC
2, Daniel, BOS
3, Tim, STL
4, Sam, SFO
5, Eric, AST 

我正在尝试使用 awk 执行此操作,但我是初学者,所以我无法找到执行此操作的方法。任何指针都会有所帮助。

【问题讨论】:

你必须使用awk吗?为什么不使用 join 命令? 【参考方案1】:

假设 CSV 中的数据与您在上面共享的数据相同。

cat f1.csv f2.csv f3.csv|awk -F',' '$2!="" && $3!=""'

【讨论】:

【参考方案2】:

请尝试在单个 awk 中关注,如果这对您有帮助,请告诉我。

awk -F, 'NR==1print;nextFNR>1a[$1]=NF>1 && a[$1]?a[$1] FS $0:(NF>1?$0:"") ENDfor(i in a)if(a[i])print a[i] | "sort"' 1.csv 2.csv 3.csv

输出如下。

ID, name, city
 1, John, NYC
 2, Daniel, BOS
 3, Tim, STL
 4, Sam, SFO
 5, Eric, AST

它也应该适用于超过 3 个文件,只有当它超过打开文件的限制时,为了避免任何 too many files opened 错误,我们必须运行以下代码。

awk -F, '
NR==1
  print;
  next

FNR==1
  if(val)
    close(val)
;
  val=FILENAME

FNR>1
  a[$1]=NF>1 && a[$1]?a[$1] FS $0:(NF>1?$0:"")

END
  for(i in a)
    if(a[i])
     print a[i] | "sort"


' 1.csv 2.csv 3.csv

【讨论】:

不需要if(val) close(val) val=FILENAMEtoo many files opened error不会来这里,awk一个一个读取文件,同时关闭文件处理程序。 不知道是谁给了我反对票,也没有告诉我理由,这让一个人灰心:(【参考方案3】:
$ cat f1
ID, name, city
1, John, NYC
2
3
4, Sam, SFO
5 

$ cat f2
ID, name, city
3, Tim, STL
2, Daniel, BOS

$ cat f3
ID, name, city
5, Eric, AST

$ awk -F, 'FNR==1i++i<3a[$1+0]=$0;nexti==3 && $1+0 in aprint a[$1+0];next1' f2 f3 f1
ID, name, city
1, John, NYC
2, Daniel, BOS
3, Tim, STL
4, Sam, SFO
5, Eric, AST

【讨论】:

【参考方案4】:

在输出中我们抑制无名记录和标题,然后按 ID 排序:

$ (head -1 1st.csv
   awk -F, 'NF > 2 && FNR > 1' 1st,2nd,3rd.csv | sort -n ) | tee combined.csv

【讨论】:

以上是关于映射多个 csv 文件中的字段并组合行的主要内容,如果未能解决你的问题,请参考以下文章

在 csv 文件中的所有行组合中应用字符串匹配逻辑 [关闭]

以编程方式将多个 SQL 列组合并存储到一个列中

C#:用 CSV 中的单列填充组合框

组合主键及JPA映射

如何在 Excel 中组合具有不同列名和列顺序的多个 CSV 文件?

如何在通过 255 字段限制的访问中组合表?