Powershell - 在csv文件中的特定列之间插入列

时间:2016-01-13 00:26:41

标签: powershell powershell-v3.0

我有2个csv文件

第一档:

firstName,secondName
1234,Value1
2345,Value1
3456,Value1
4567,Value3
7645,Value3

第二档:

firstName,fileSplitter,Csv2ColumnOne,Csv2ColumnTwo,Csv2ColumnThree
1234,,1234,abc,Value1
1234,,1234,asd,Value1
3456,,3456,qwe,Value1
4567,,4567,mnb,Value1

我想在列secondNamefirstName之间的第二个文件中插入列fileSplitter

结果应如下所示:

firstName,secondName,fileSplitter,Csv2ColumnOne,Csv2ColumnTwo,Csv2ColumnThree
1234,Value1,,1234,abc,Value1
1234,Value1,,1234,asd,Value1
3456,Value1,,3456,qwe,Value1
4567,Value3,,4567,mnb,Value1

我正在尝试以下代码:

Function InsertColumnInBetweenColumns
{
Param ($FirstFileFirstColumnTitle, $firstFile, [string]$1stColumnName, [string]$2ndColumnName, [string]$columnMergedFileBeforeInput)

Write-Host "Creating hash table with columns values `"$1stColumnName`" `"$2ndColumnName`" From $OimFileWithMatches"
$hashFirstFileTwoColumns = @{}
Import-Csv $firstFile | ForEach-Object {$hashFirstFileTwoColumns[$_.$1stColumnName] = $_.$2ndColumnName}
Write-Host "Complete."

Write-Host "Appending Merge file with column `"$2ndColumnName`" from file $secondCsvFileWithLocalPath"
Import-Csv $outputCsvFileWithLocalPath | Select-Object $columnMergedFileBeforeInput, @{n=$2ndColumnName; e={
if ($hashFirstFileTwoColumns.ContainsKey($_.$FirstFileFirstColumnTitle)) {
    $hashFirstFileTwoColumns[$_.$FirstFileFirstColumnTitle]
} Else {
    'Not Found'
}}}, * | Export-Csv "$outputCsvFileWithLocalPath-temp" -NoType -Force
Move-Item "$outputCsvFileWithLocalPath-temp" $outputCsvFileWithLocalPath -Force
Write-Host "Complete."
Write-Host ""
}

将在第一个文件中找到的每个列的for循环中调用此函数(可以包含不确定的数字)。为了测试,我只使用第一个文件中的2列。

我收到错误输出结果如下:

Select : Property cannot be processed because property "firstName" already exists.
At C:\Scripts\Tests\Compare2CsvFilesOutput1WithMatchesOnly.ps1:490 char:43
+     Import-Csv $outputCsvFileWithLocalPath | Select $columnMergedFileBeforeInput, @ ...
+                                              ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidOperation: (@{firstName=L...ntName=asdfas}:PSObject) [Select-Object], PSArgume
   ntException
    + FullyQualifiedErrorId : AlreadyExistingUserSpecifiedPropertyNoExpand,Microsoft.PowerShell.Commands.SelectObjectC
   ommand

我知道问题在于Select-Object $columnMergedFileBeforeInput,

如何获取循环语句以在前一列(指定名称)之间插入列,并使用*附加其余内容?

更新

只是一个fyi,将此行Select-Object $columnMergedFileBeforeInput, @{n=$2ndColumnName.....更改为此行Select-Object @{n=$2ndColumnName.....有效,它只是按顺序附加列。这就是为什么我试图在其间插入列。也许如果我这样做,但使用for循环向后插入列,这将工作...

2 个答案:

答案 0 :(得分:2)

不确定这是否是最有效的方法,但它应该可以解决问题。它只是将属性添加到file2的记录中,然后重新排序输出,因此secondName是第二列。您也可以将结果输出到csv(ConvertTo-Csv)。

$file1 = Import-Csv -Path file1.csv
$file2 = Import-Csv -Path file2.csv

$results = @()
ForEach ($record In $file2) {
   Add-Member -InputObject $record -MemberType NoteProperty -Name secondName -Value $($file1 | ? { $_.firstName -eq $record.firstName } | Select -ExpandProperty secondName)
   $results += $record
}

$results | Select-Object -Property firstName,secondName,fileSplitter,Csv2ColumnOne,Csv2ColumnTwo,Csv2ColumnThree

答案 1 :(得分:0)

我创建了以下功能。它的作用是找到匹配(在本例中为“firstname”)并将匹配的列名添加到新数组中,而不是匹配所在的列名(在我糟糕的英语中很难解释)。

Add-ColumnAfterMatchingColumn -MainFile C:\Temp\file1.csv -MatchingFile C:\Temp\file2.csv -MatchColumnName "firstname" -MatchingColumnName "secondname" | ft

firstName secondname fileSplitter Csv2ColumnTwo Csv2ColumnThree Csv2ColumnOne
--------- ---------- ------------ ------------- --------------- -------------
1234      Value1                  abc           Value1          1234         
1234      Value1                  asd           Value1          1234         
3456      Value1                  qwe           Value1          3456         
4567      Value3                  mnb           Value1          4567         

运行此功能时,您将获得以下输出:

client.UploadStringCompleted += new UploadStringCompletedEventHandler(delegate(object sender, UploadStringCompletedEventArgs e)
{
    soapResult = e.Result;
});