使用 StreamReader 在每行的多个列上复制 Vlookup 的问题

Issue using StreamReader to replicate Vlookup on multiple columns per row

我有一个非常大的竖线分隔文件(约百万行),其中包含 11 列,其中 8 列包含一个键。

Master_File.csv

Year|Key1|Key2|Key3|Key4|Key5|Key6|Key7|Key8|Location|Name
2019|1235|2345|1231|1235|3536|1231|1234|3624|Site6|Storage
2019|2345|2345|1231|1231|3536|1235|1234|1231|Site8|Storage
2019|3536|2345|3536|1235|2345|1235|3536|1235|Site7|Storage
2019|2345|1235|1231|1235|1231|3452|1231|2345|Site9|Storage

我有另一个用竖线分隔的小文件(~8k 行),其中包含 2 列、键和值。

Lookup_File.csv

Key|Value
1235|Value 1235
2345|Value 2345
1231|Value 1231
1234|Value 1234
3536|Value 3536
3452|Value 3452
1234|Value 1234
3624|Value 3624

我需要遍历 Master_File.csv 的每一行并将键替换为 Lookup_File.csv 中的值。结果应该是这样的。

Year|Key1|Key2|Key3|Key4|Key5|Key6|Key7|Key8|Location|Name
2019|Value 1235|Value 2345|Value 1231|Value 1235|Value 3536|Value 1231|Value 1234|Value 3624|Site6|Storage
2019|Value 2345|Value 2345|Value 1231|Value 1231|Value 3536|Value 1235|Value 1234|Value 1231|Site8|Storage
2019|Value 3536|Value 2345|Value 3536|Value 1235|Value 2345|Value 1235|Value 3536|Value 1235|Site7|Storage
2019|Value 2345|Value 1235|Value 1231|Value 1235|Value 1231|Value 3452|Value 1231|Value 2345|Site9|Storage

下面的代码是我到目前为止的代码,但问题是它只运行了 Master_File 一次,只替换了第一个键。

$content = "c:\Lookup_File.csv"
$LookupFile = New-Object -TypeName System.IO.StreamReader - ArgumentList $content
$skip1 = $LookupFile.ReadLine()

$src = "c:\Master_File.csv"
$MasterFile = New-Object -TypeName System.IO.StreamReader -ArgumentList $src

$header = $Masterfile.ReadLine()
$outData = New-Object -TypeName System.Text.StringBuilder
[void]$outData.AppendLine($header)

while ($line = $LookupFile.ReadLine())
{
    $key = ($line -split "\|")[0]
    $value = ($line -split "\|")[1]
    while ($row = $MasterFile.ReadLine()){
        $row = $row -Replace $key, $value
        [void]$outData.AppendLine($row)
    }
}
$outData.ToString() | Out-File -FilePath "c:\Master_File_Out.csv" -Encoding ascii

我得到这个作为输出。

Year|Key1|Key2|Key3|Key4|Key5|Key6|Key7|Key8|Location|Name
2019|Value 1235|2345|1231|Value 1235|3536|1231|1234|3624|Site7|Storage
2019|2345|2345|1231|1231|3536|Value 1235|1234|1231|Site8|Storage
2019|3536|2345|3536|Value 1235|2345|Value 1235|3536|Value 1235|Site9|Storage
2019|2345|Value 1235|1231|Value 1235|1231|3452|1231|2345|Site11|Storage

我真的很难遍历 Master_File 的每一行并用值替换 8 个键中的每一个。

如有任何帮助,我们将不胜感激!

根据我的评论,尝试:

## Q:\Test19\SO_57659677.ps1

$hash = @{}
Import-Csv '.\Lookup_File.csv' -Delimiter '|' | ForEach {$Hash[$_.Key]=$_.Value}

$Master = Import-Csv '.\Master_File.csv' -Delimiter '|'

ForEach($Item in $Master){
    For($i=1;$i -le 8;$i++){
       if($hash.ContainsKey($item."Key$i")){
           $item."Key$i" = $hash[$item."Key$i"]
       }
    }
}

$Master |ft -auto

# $Master | Export-Csv "c:\Master_File_Out.csv" -Delimiter '|' -NoTypeInformation 
# To have no double quotes in the ouptput file
# ($Master | ConvertTo-Csv -Delimiter '|' -NoTypeInformation) -replace '"' | Set-Content -"c:\Master_File_Out.csv" Encoding ascii

示例输出:

> $Master|ft -auto

Year Key1       Key2       Key3       Key4       Key5       Key6       Key7       Key8       Location
---- ----       ----       ----       ----       ----       ----       ----       ----       --------
2019 Value 1235 Value 2345 Value 1231 Value 1235 Value 3536 Value 1231 Value 1234 Value 3624 Site6
2019 Value 2345 Value 2345 Value 1231 Value 1231 Value 3536 Value 1235 Value 1234 Value 1231 Site8
2019 Value 3536 Value 2345 Value 3536 Value 1235 Value 2345 Value 1235 Value 3536 Value 1235 Site7
2019 Value 2345 Value 1235 Value 1231 Value 1235 Value 1231 Value 3452 Value 1231 Value 2345 Site9

编辑

通过将 ColumnNames 读入数组并使用索引 1..8 添加了一个抽象级别

## Q:\Test19\SO_57659677_2.ps1
$hash = @{}
Import-Csv '.\Lookup_File.csv' -Delimiter '|' | ForEach {$Hash[$_.Key]=$_.Value}

$Master = Import-Csv '.\Master_File.csv' -Delimiter '|'
$ColNames = $Master[0].psobject.properties.name

ForEach($Item in $Master){
    For($i=1;$i -le 8;$i++){
       if($hash.ContainsKey($item."$($ColNames[$i])")){
           $item."$($ColNames[$i])" = $hash[$item."$($ColNames[$i])"]
       }
    }
}

$Master |ft -auto

> .\SO_57659677_2.ps1

Year Working    Approved   Rejected   WhatIf1    Whatif2    Submitted  Proposed   Syncd      Location
---- -------    --------   --------   -------    -------    ---------  --------   -----      --------
2019 Value 1235 Value 2345 Value 1231 Value 1235 Value 3536 Value 1231 Value 1234 Value 3624 Site6
2019 Value 2345 Value 2345 Value 1231 Value 1231 Value 3536 Value 1235 Value 1234 Value 1231 Site8
2019 Value 3536 Value 2345 Value 3536 Value 1235 Value 2345 Value 1235 Value 3536 Value 1235 Site7
2019 Value 2345 Value 1235 Value 1231 Value 1235 Value 1231 Value 3452 Value 1231 Value 2345 Site9

几乎一样。

$hash=@{}
import-csv lookup_file.csv -delimiter '|' | foreach {
  $hash[$_.key] = $_.value
}

import-csv master_file.csv -delimiter '|' | foreach {
  foreach ($i in 1..8) {
    $_."key$i" = $hash[$_."key$i"]
  }
  $_
} | export-csv master_file_out.csv -delimiter '|'