所以我整天都在试图通过互联网寻找一种结合多个CSV文件的方法。无论我查找过30多种PowerShell方法中的哪一种,我都会遇到问题。
我正在尝试将多个CSV文件组合成一个,基本上采用“完全连接”方式。我需要最终得到所有CSV组合的所有行和所有列,除了我想根据公共标识符组合行。这个讨论:“Merging two CSV files by shared column”正是我正在做的两个例外。首先它只为两个CSV构建,如果两个CSV都不包含“名称”,它会丢弃行。我想保留行,即使它不在两个CSV中,只是创建空白条目,其他CSV中没有数据。
CSV1.csv
Name,Attrib1,Attrib2
VM1,111,True
VM2,222,False
CSV2.csv
Name,AttribA,Attrib1
VM1,AAA,111
VM3,CCC,333
CSV3.csv
Name,Attrib2,AttribB
VM2,False,YYY
VM3,True,ZZZ
所需的综合结果:
Name,Attrib1,Attrib2,AttribA,AttribB
VM1,111,True,AAA,
VM2,222,False,,YYY
VM3,333,True,CCC,ZZZ
任何人对此都有任何想法吗?如果您需要我的更多信息,请告诉我。
更新:这是我目前使用SQLite shell进行的代码尝试:
$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 Combination \ csv1.csv第1行:预计5列数据但找到6
答案 0 :(得分:0)
试试这个:
$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。
答案 1 :(得分:0)
我创建了一个名为Merge-Object
(别名为Merge
)的Join-Object
代理命令,因为似乎经常使用与SQL MERGE语句稍微相似的合并对象。 Merge-Object
命令的默认参数设置为:JoinType = 'Full'
和MergeExpression = {{$RightOrLeft.$_}}
。这意味着所有左侧对象都将使用right属性值进行更新,并且左侧对象列表中不存在的右侧对象将添加到结果中:
Import-Csv CSV1.csv |
Merge (Import-Csv CSV2.csv) -On Name |
Merge (Import-Csv CSV3.csv) -On Name |
Format-Table
结果:
Name Attrib1 Attrib2 AttribA AttribB
---- ------- ------- ------- -------
VM1 111 True AAA
VM2 222 False YYY
VM3 333 True CCC ZZZ
答案 2 :(得分:0)
您可以使用出色的命令行工具:Miller(https://jsfiddle.net/aslamb/sfoavupd/2/)。
使用
mlr --csv reshape -r "^A" -o item,value then reshape -s item,value \
then unsparsify --fill-with "" *.csv
你有
Name,Attrib1,Attrib2,AttribA,AttribB
VM1,111,True,AAA,
VM2,222,False,,YYY
VM3,333,True,CCC,ZZZ
作为输入,我已经使用了这3个文件
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 http://johnkerl.org/miller/doc/