如何合并两个 csv 文件中的所有内容,其中记录与 1 列匹配

2023-12-07

我有两个 csv 文件。他们都有SamAccountName共同点。用户记录可能会也可能不会为两个文件之间的每条记录找到匹配项(这一点非常重要)。

我基本上试图将所有列(及其值)合并到一个文件中(基于第一个文件中找到的 SamAccountNames...)。

如果在第二个文件中找不到 SamAccountName,则应在合并文件中添加该用户记录的所有空值(因为在第一个文件中找到该记录)。

如果在第二个文件中找到 SamAccountName,但在第一个文件中没有找到,则应忽略合并该记录。

每个文件中的列数可能有所不同(5、10、2,依此类推...)。

Function MergeTwoCsvFiles
{
    Param ([String]$baseFile, [String]$fileToBeMerged, [String]$columnTitleLineInFileToBeMerged)
    
    $baseFileCsvContents = Import-Csv $baseFile
    $fileToBeMergedCsvContents = Import-Csv $fileToBeMerged
    
    $baseFileContents = Get-Content $baseFile
    
    $baseFileContents[0] += "," + $columnTitleLineInFileToBeMerged
    
    $baseFileCsvContents | ForEach-Object {
        $matchFound = $False
        $baseSameAccountName = $_.SamAccountName
        [String]$mergedLineInFile = $_
        
        [String]$lineMatchFound = $fileToBeMergedCsvContents | Where-Object {$_.SamAccountName -eq $baseSameAccountName}
        Write-Host '$mergedLineInFile =' $mergedLineInFile
        Write-Host '$lineMatchFound =' $lineMatchFound
        Exit
    }
}

问题是,文件中的记录被写入哈希表而不是类似行的字符串(如果您将其视为 .txt)。所以我不太确定该怎么做......

添加结果 csv 示例文件...

第一个 CSV 文件

"SamAccountName","sn","GivenName"
"PBrain","Pinky","Brain"
"JSteward","John","Steward"
"JDoe","John","Doe"
"SDoo","Scooby","Doo"

第二个 CSV 文件

"SamAccountName","employeeNumber","userAccountControl","mail"
"KYasunori","678213","546","[email protected]"
"JSteward","43518790","512","[email protected]"
"JKibogabi","24356","546","[email protected]"
"JDoe","902187u4","1114624","[email protected]"
"CStrife","54627","512","[email protected]"

预期合并的 CSV 文件

"SamAccountName","sn","GivenName","employeeNumber","userAccountControl","mail"
"PBrain","Pinky","Brain","","",""
"JSteward","John","Steward","43518790","512","[email protected]"
"JDoe","John","Doe","902187u4","1114624","[email protected]"
"SDoo","Scooby","Doo","","",""

注意:这将是合并多个文件的循环过程的一部分,因此我想避免对标题名称进行硬编码(使用$_.SamAccountName作为例外)

尝试“不安的1987”的建议(不起作用)

$baseFileCsvContents = Import-Csv 'D:\Scripts\Powershell\Tests\base.csv'
$fileToBeMergedCsvContents = Import-Csv 'D:\Scripts\Powershell\Tests\lookup.csv'
$resultsFile = 'D:\Scripts\Powershell\Tests\MergedResults.csv'
$resultsFileContents = @()

$baseFileContents = Get-Content 'D:\Scripts\Powershell\Tests\base.csv'

$recordsMatched = compare-object $baseFileCsvContents $fileToBeMergedCsvContents -Property SamAccountName

switch ($recordsMatched)
{
    '<=' {}
    '=>' {}
    '==' {$resultsFileContents += $_}
}

$resultsFileCsv = $resultsFileContents | ConvertTo-Csv
$resultsFileCsv | Export-Csv $resultsFile -NoTypeInformation -Force

输出给出一个空白文件:(


下面的代码根据您提供的输入输出所需的结果。

function CombineSkip1($s1, $s2){
    $s3 = $s1 -split ',' 
    $s2 -split ',' | select -Skip 1 | % {$s3 += $_}
    $s4 = $s3 -join ', '

    $s4
}

Write-Output "------Combine files------"

# content
$c1 = Get-Content D:\junk\test1.csv
$c2 = Get-Content D:\junk\test2.csv

# users in both files, could be a better way to do this
$t1 = $c1 | ConvertFrom-Csv
$t2 = $c2 | ConvertFrom-Csv
$users = $t1 | Select SamAccountName

# generate final, combined output
$combined = @()
$combined += CombineSkip1 $c1[0] $c2[0]

$c2PropCount = ($c2[0] -split ',').Count - 1
$filler = (', ""' * $c2PropCount)

for ($i = 1; $i -lt $c1.Count; $i++){
    $user = $c1[$i].Split(',')[0]
    $u2 = $c2 | where {([string]$_).StartsWith($user)}
    if ($u2)
    {
        $combined += CombineSkip1 $c1[$i] $u2
    }
    else
    {
        $combined += ($c1[$i] + $filler)
    }
}

# write to output and file
Write-Output $combined
$combined | Set-Content -Path D:\junk\test3.csv -Force
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何合并两个 csv 文件中的所有内容,其中记录与 1 列匹配 的相关文章

随机推荐