我有第一个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
如您所见,问题在于2个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'
答案 0 :(得分:3)
您建议的内容不是很有用,甚至不是有效的CSV。恕我直言,只有两个结果才有意义:
此:
Server1,Info1,Server2,Info2
server1,item1,server2,item2
server1,item1,server2,item2
或者这个:
Server,Info
server1,item1
server1,item1
server2,item2
server2,item2
第一种方法:
$csv1 = Import-Csv ".\Powershell test\A.csv"
$csv2 = Import-Csv ".\Powershell test\B.csv"
$merged = for($i = 0; $i -lt $csv1.Count; $i++) {
$new = new-object psobject
$entry1 = $csv1[$i]
$entry1 | Get-Member -Type NoteProperty | foreach {
Add-Member -InputObject $new -MemberType NoteProperty -Name ($_.Name + "1") -Value $entry1.($_.Name)
}
$entry2 = $csv2[$i]
$entry2 | Get-Member -Type NoteProperty | foreach {
Add-Member -InputObject $new -MemberType NoteProperty -Name ($_.Name + "2") -Value $entry2.($_.Name)
}
$new
}
$merged | Export-Csv ".\Powershell test\merged.csv"
第二种方法:
$csv1 = Import-Csv ".\Powershell test\A.csv"
$csv2 = Import-Csv ".\Powershell test\B.csv"
$merged = $csv1 + $csv2
$merged | Export-Csv ".\Powershell test\merged.csv"
更新
如果您想精确地输出(并且文件肯定具有相同的标题和行数),则可以先使用唯一的标题,然后稍后再重命名:
$csv1 = Import-Csv ".\Powershell test\A.csv"
$csv2 = Import-Csv ".\Powershell test\B.csv"
$merged = for($i = 0; $i -lt $csv1.Count; $i++) {
$new = New-Object PSObject
("Server", "Info") | foreach {
Add-Member -InputObject $new -MemberType NoteProperty -Name ($_ + "1") -Value $csv1[$i].$_
Add-Member -InputObject $new -MemberType NoteProperty -Name ($_ + "2") -Value $csv2[$i].$_
}
$new
}
$header = $true
$merged | ConvertTo-Csv -NoTypeInformation | foreach {
if ($header) {
$header = $false
# remove the numbers from the headers
$_ -replace "\d", ""
}
else { $_ }
} | Out-File ".\Powershell test\merged.csv"
说明:
Count
在Powershell中可用于所有集合,并且比Length
更安全,后者仅是数组的属性。但是在这种情况下,两者都应该起作用。
在循环中,将创建一个新的空对象(带有New-Object
),然后通过添加已解析的CSV对象(带有Add-Member
)的成员来填充。在属性名称中添加了一个计数器,以使它们唯一。
然后将这些对象($merged
)的集合转换为CSV,删除标题行中的数字,并将所有内容保存到文件中。
答案 1 :(得分:1)
由于似乎有几种用例来识别不相关的属性键而不是合并它们,所以我添加了一个新功能。 Join-Object
cmdlet的-Unify
(通常是//别名-Merge
参数)现在接受一个或两个动态键来区分联接中无关的列对。
-Unify
(别名-Merge
)参数定义了如何统一左侧和右侧 与无关的公共属性有关的正确对象。的 常见属性可以识别(<String>[,<String>]
)或合并 (<ScriptBlock>
)。默认情况下,不相关的公共属性为 使用以下表达式合并:{$LeftOrVoid.$_, $RightOrVoid.$_}
<String>[,<String>]
如果该值不是ScriptBlock
,则假定为 一个字符串数组,其中有一个或两个项定义了左键和右键 格式。如果项目中包含星号(*
),则星号为 替换为属性名称,否则该项目将用于 在属性名称前添加前缀。注意:连续的数字将自动添加到公用 属性名称(如果已使用)。
...
示例:
$Csv1 = ConvertFrom-Csv 'Server,Info
server1,item1
server1,item1'
$Csv2 = ConvertFrom-Csv 'Server,Info
server2,item2
server2,item2'
$Csv1 | Join $Csv2 -Unify *1, *2
结果:
Server1 Server2 Info1 Info2
------- ------- ----- -----
server1 server2 item1 item2
server1 server2 item1 item2