首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >合并多个CSV文件

合并多个CSV文件
EN

Stack Overflow用户
提问于 2013-07-19 17:26:29
回答 3查看 2.8K关注 0票数 4

所以我一整天都在攻击互联网,寻找一种合并多个CSV文件的方法。我总是遇到一个问题,不管我查到了哪一种30+ PowerShell方法。

我试图将多个CSV文件合并成一个文件,本质上是“完全连接”风格。我需要得到所有CSV的所有行和所有列的合并,但我想根据公共标识符组合行的除外。这个讨论:"通过共享列合并两个CSV文件",除了两个例外,它就是我想要做的事情。首先,它只为两个CSV构建;其次,如果两个CSV都不包含“名称”,则会删除行。我想保留行,即使它不在两个CSV中,只需在其他CSV中没有数据的地方创建空白条目。

CSV1.csv

代码语言:javascript
复制
Name,Attrib1,Attrib2

VM1,111,True
VM2,222,False

CSV2.csv

代码语言:javascript
复制
Name,AttribA,Attrib1

VM1,AAA,111
VM3,CCC,333

CSV3.csv

代码语言:javascript
复制
Name,Attrib2,AttribB

VM2,False,YYY
VM3,True,ZZZ

期望的联合结果:

代码语言:javascript
复制
Name,Attrib1,Attrib2,AttribA,AttribB

VM1,111,True,AAA,
VM2,222,False,,YYY
VM3,333,True,CCC,ZZZ

有人对这件事有什么想法吗?如果你需要我那边的更多信息,请告诉我。

更新:下面是使用SQLite外壳程序的当前代码尝试:

代码语言:javascript
复制
$db  = Join-Path $env:TEMP 'temp.db'
$dir = "C:\Users\UserName\Downloads\CSV Combination"
$outfile = Join-Path $dir 'combined.csv'

@"
CREATE TABLE a (Name varchar(20),OS varchar(20),IP varchar(20),Contact varchar(20),Application varchar(20));
CREATE TABLE b (Name varchar(20));
CREATE TABLE c (Name varchar(20),Quiesce varchar(20));
CREATE TABLE d (Name varchar(20),NoQuiesce varchar(20));
.mode csv
.import '$((Join-Path $dir csv1.csv) -replace '\\', '\\')' a
.import '$((Join-Path $dir csv2.csv) -replace '\\', '\\')' b
.import '$((Join-Path $dir csv3.csv) -replace '\\', '\\')' c
.import '$((Join-Path $dir csv4.csv) -replace '\\', '\\')' d
SELECT a.Name,a.OS,a.IP,a.Contact,a.Application,c.Quiesce,d.NoQuiesce
FROM a
  LEFT OUTER JOIN b ON a.Name = b.Name
  LEFT OUTER JOIN c ON a.Name = c.Name
  LEFT OUTER JOIN d ON a.Name = d.Name
UNION
SELECT b.Name,a.OS,a.IP,a.Contact,a.Application,c.Quiesce,d.NoQuiesce
FROM b
  LEFT OUTER JOIN a ON a.Name = b.Name
  LEFT OUTER JOIN c ON b.Name = c.Name
  LEFT OUTER JOIN d ON c.Name = d.Name
UNION
SELECT c.Name,a.OS,a.IP,a.Contact,a.Application,c.Quiesce,d.NoQuiesce
FROM c
  LEFT OUTER JOIN a ON a.Name = c.Name
  LEFT OUTER JOIN b ON b.Name = c.Name
  LEFT OUTER JOIN d ON c.Name = d.Name;
"@ | filesystem::"C:\Users\UserName\Downloads\CSV Combination\sqlite3.exe" $db >$outfile

Remove-Item $db

这当前返回以下错误消息:

sqlite3.exe :错误: C:\Users\brandon.andritsch\Downloads\CSV组合\csv1.csv第1行:预期的5列数据但找到6列

EN

回答 3

Stack Overflow用户

发布于 2019-02-24 19:05:00

我已经创建了一个名为Join-Object代理命令Merge-Object (别名Merge),因为经常使用与SQL 合并语句稍有相似的合并对象。Merge-Object命令的默认参数设置为:JoinType = 'Full'Property= {{If ($Null -ne $RightIndex) {$Right.$_} Else {$Left.$_}}}}。这意味着所有左对象都用右属性值更新,而左侧对象列表中不存在的右对象被添加到结果中:

代码语言:javascript
复制
Import-Csv CSV1.csv | 
Merge (Import-Csv CSV2.csv) -On Name | 
Merge (Import-Csv CSV3.csv) -On Name |
Format-Table

结果:

代码语言:javascript
复制
Name Attrib1 Attrib2 AttribA AttribB
---- ------- ------- ------- -------
VM1  111     True    AAA
VM2  222     False           YYY
VM3  333     True    CCC     ZZZ
票数 2
EN

Stack Overflow用户

发布于 2019-02-24 20:02:58

您可以使用一个很好的命令行工具: Miller (http://johnkerl.org/miller/doc/)。

使用

代码语言:javascript
复制
mlr --csv reshape -r "^A" -o item,value then reshape -s item,value \
then unsparsify --fill-with ""  *.csv

你有

代码语言:javascript
复制
Name,Attrib1,Attrib2,AttribA,AttribB
VM1,111,True,AAA,
VM2,222,False,,YYY
VM3,333,True,CCC,ZZZ

作为输入,我使用了以下3个文件

代码语言:javascript
复制
Name,Attrib1,Attrib2
VM1,111,True
VM2,222,False

Name,Attrib2,AttribB
VM2,False,YYY
VM3,True,ZZZ

Name,AttribA,Attrib1
VM1,AAA,111
VM3,CCC,333

还有一个win exe https://github.com/johnkerl/miller/releases

关于该命令的一些注释:

  • reshape -r "^A" -o item,value,将输入的CSV从宽转换为长,将其应用于名称以“A”开头的所有字段;
  • reshape -s item,value,将以前的输出从长到宽;
  • unsparsify --fill-with "",以管理所有输入记录上的字段名。对于给定记录中不存在但在其他记录中存在的字段名,则填充"“值。
票数 1
EN

Stack Overflow用户

发布于 2013-07-19 18:23:51

试试这个:

代码语言:javascript
复制
$db  = Join-Path $env:TEMP 'temp.db'
$dir = "C:\some\folder"
$outfile = Join-Path $dir 'combined.csv'

@"
CREATE TABLE a (Name varchar(20),Attrib1 varchar(20),Attrib2 varchar(20));
CREATE TABLE b (Name varchar(20),AttribA varchar(20),Attrib1 varchar(20));
CREATE TABLE c (Name varchar(20),Attrib2 varchar(20),AttribB varchar(20));
.mode csv
.import '$((Join-Path $dir csv1.csv) -replace '\\', '\\')' a
.import '$((Join-Path $dir csv2.csv) -replace '\\', '\\')' b
.import '$((Join-Path $dir csv3.csv) -replace '\\', '\\')' c
SELECT a.Name,a.Attrib1,a.Attrib2,b.AttribA,c.AttribB
FROM a
  LEFT OUTER JOIN b ON a.Name = b.Name
  LEFT OUTER JOIN c ON a.Name = c.Name
UNION
SELECT b.Name,a.Attrib1,a.Attrib2,b.AttribA,c.AttribB
FROM b
  LEFT OUTER JOIN a ON a.Name = b.Name
  LEFT OUTER JOIN c ON b.Name = c.Name
UNION
SELECT c.Name,a.Attrib1,a.Attrib2,b.AttribA,c.AttribB
FROM c
  LEFT OUTER JOIN a ON a.Name = c.Name
  LEFT OUTER JOIN b ON b.Name = c.Name;
"@ | sqlite3 $db >$outfile

Remove-Item $db

为此,您需要SQLite命令行shell。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/17752072

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档