我有第一个CSV:
Server,Info
server1,item1
server1,item1
第二个CSV:
Server,Info
server2,item2
server2,item2
我试图得到这样的输出:
Server,Server,Info,Info
server1,server2,item1,item2
server1,server2,item1,item2
如您所见,问题在于两个CSV的头文件具有相同的名称,如果我将它们解析为对象并循环键,这将导致问题。
所以我尝试合并它们,然后将它们重新排序为字符串,但我的头脑无法想象如何在最后一个for
循环中做到这一点:
$file1 = Get-Content ".\Powershell test\A.csv"
$file2 = Get-Content ".\Powershell test\B.csv"
$content = for ($i = 0; $i -lt $file1.Length; $i++) {
'{0},{1}' -f $file1[$i].Trim(), $file2[$i].Trim()
}
$content | Out-File ".\Powershell test\merged.csv"
$firstFileParsed = Import-Csv -Path ".\Powershell test\B.csv"
$secondFileParsed = Import-Csv -Path ".\Powershell test\B.csv"
$secondFilePath = ".\Powershell test\B.csv"
$contentOf2ndFile = Get-Content $secondFilePath
$csvColumnNames = (Get-Content '.\Powershell test\B.csv' |
Select-Object -First 1).Split(",")
$newColumns = @()
foreach($header in $csvColumnNames) {
$newColumns += $header
}
$newColumns = $newColumns -join ","
$contentOf2ndFile[0] = $newColumns
$contentOf2ndFile | Out-File ".\Powershell test\temp.csv"
$tempObject = Import-Csv -Path ".\Powershell test\temp.csv"
$tempFile = Get-Content ".\Powershell test\temp.csv"
$array = @()
$tempArr = @()
for ($i = 0; $i -lt $file1.Length; $i++) {
$tempArr1 = $file1[$i] -split ","
$tempArr2 = $tempFile[$i] -split ","
for ($j = 0; $j -lt $tempArr1.Length; $j++) {
$tempArr += $tempArr1[$j] + "," + $tempArr2[$j]
$tempArr
}
$array += $tempArr
}
$array | Out-File '.\Powershell test\merged.csv'
2条答案
按热度按时间lawou6xi1#
你建议的不是很有用,甚至不是有效的CSV。IMHO只有两个结果是有意义的:
这一点:
或者这个:
第一种方法:
第二种方法:
更新
如果你想要准确的输出(并且文件肯定有相同的标题和行数),你可以先使用唯一的标题,然后简单地重命名它们:
Count
在Powershell中可用于所有集合,并且比Length
更安全,后者仅是数组的属性。但在这种情况下,两者都应该起作用。在循环中,创建一个新的空对象(使用
New-Object
),然后通过添加解析的CSV对象的成员(使用Add-Member
)来填充。属性名称中添加了一个计数器,以使其唯一。然后将这些对象的集合(
$merged
)转换为CSV,删除标题行中的数字,并将所有内容保存到文件中。uajslkp62#
由于似乎有几个用例可以识别不相关的属性键,而不是将它们合并,因此我添加了一个新特性。
Join-Object
cmdlet的-Unify
(正式名称/别名为-Merge
参数)现在接受一个或两个动态键来区分联接中不相关的列对。-Unify
(别名-Merge
)参数定义了如何相对于不相关的公共属性统一左对象和右对象。可以辨别(<String>[,<String>]
)或合并(<ScriptBlock>
)公共属性。默认情况下,将使用表达式合并不相关的公共属性:{$LeftOrVoid.$_, $RightOrVoid.$_}
<String>[,<String>]
如果值不是ScriptBlock
,则假定它是一个字符串数组,其中包含一个或两个定义左右键格式的项。如果项目包含星号(*
),星号将替换为属性名称,否则项目将用作属性名称的前缀。注意:如果已使用,则会自动将连续数字添加到公用属性名称中。
...
示例:
结果: