【问题标题】:Combine columns from 2 CSV files合并来自 2 个 CSV 文件的列
【发布时间】:2014-04-16 09:50:50
【问题描述】:

这似乎很基本,但我无法在任何地方找到或弄清楚 我有 2 个 CSV 文件,我想创建一个包含匹配列的新文件。

巨大的.csv

"Share","Group","Username","Name","LogonScript"
"\\SHARE\TEST","Group Test","administrator","Administrator name","(no-script)"
"\\SHARE\TEST","Group Test","user1","user name1","logon.bat"
"\\SHARE\TEST","Group Test","user2","user name2","logon.bat"

Little.csv

"Username","Computer","NetworkDrives"
administrator,PC100,M:\\share\it#N:\\share\test
user2,PC102,M:\\share\it#N:\\share\test

期望的输出:

输出.csv

"Share","Group","Username","Name","LogonScript","Computer","NetworkDrives"
"\\SHARE\TEST","Group Test","administrator","Administrator name","(no-script)",PC100,M:\\share\it#N:\\share\test
"\\SHARE\TEST","Group Test","user1","user name1","logon.bat",,
"\\SHARE\TEST","Group Test","user2","user name2","logon.bat",PC102,M:\\share\it#N:\\share\test

这是我正在使用的代码:

$HugeFile = Import-Csv -Path .\Huge.csv
$LittleFile = Import-Csv -Path .\Little.csv

ForEach ($entryh in $HugeFile) {
    $o | add-member NoteProperty -Name "Share" -Value ($entryh.Share)
    $o | add-member NoteProperty  -Name "Group" -Value ($entryh.Group)
    $o | add-member NoteProperty  -Name "Username" -Value ($entryh.Username)
    $o | add-member NoteProperty  -Name "Name" -Value ($entryh.Name)
    $o | add-member NoteProperty -Name "LogonScript" -Value  
    ($entryhu.LogonScript)

    ForEach ($entryl in $LittleFile) {
        If ($($entryh.Username) -eq  $($entryl.Username)) {
            $o | add-member NoteProperty -Name "Computer" -Value ""
            ($entryl.Computer)

            $o | add-member NoteProperty -Name "NetworkDrives" -Value ""
            ($entryl.NetworkDrives)
        } Else {
            $o | add-member NoteProperty -Name "Computer" -Value "," -Force
            $o | add-member NoteProperty -Name "NetworkDrives" -Value "," -Force
        }

        $o | Export-Csv -NoTypeInformation .\output.csv
    }
}
}

我的代码不起作用。 :/

我的第二个问题是我正在考虑是否有更好的选择,因为对于Huge.csv 中的每个“用户名”,我必须与Little.csv 中的“用户名”进行比较。

也许创建一个哈希表可能更理想。 Concat Computer and Network 创造价值? 喜欢:

key                 Computer+NetworkDrive
-----------         ---------------------
administrator       PC100,M:\\share\it#N:\\share\test
user2               PC102,M:\\share\it#N:\\share\test

非常感谢!

编辑 谢谢@Ansgar-Wiechers

【问题讨论】:

  • 如果其中一个或多个可能为空,则在哈希表值中组合值可能会变得很棘手。您最好使用一对它们 - 一个用于计算机,一个用于 NetworkDrive,两者都使用用户名。

标签: powershell csv


【解决方案1】:

是的,哈希表可能是解决此问题的最佳方式。我会这样做:

$additionalData = @{}
Import-Csv .\Little.csv | % {
  $additionalData[$_.Username] = $_.Computer, $_.NetworkDrives
}

Import-Csv .\Huge.csv `
  | select Share, Group, Username, Name, LogonScript, @{n='Computer';e={}},
           @{n='NetworkDrives';e={}} `
  | % {
    if ( $additionalData.ContainsKey($_.Username) ) {
      $_.Computer      = $additionalData[$_.Username][0]
      $_.NetworkDrives = $additionalData[$_.Username][1]
    }
    $_
  } | Export-Csv -NoTypeInformation .\output.csv

或者,按照@mjolinor 的建议,为计算机和网络驱动器使用单独的哈希表:

$computers = @{}
$netDrives = @{}
Import-Csv .\Little.csv | % {
  $computers[$_.Username] = $_.Computer
  $netDrives[$_.Username] = $_.NetworkDrives
}

Import-Csv .\Huge.csv `
  | select Share, Group, Username, Name, LogonScript, @{n='Computer';e={}},
           @{n='NetworkDrives';e={}} `
  | % {
    if ( $computers.ContainsKey($_.Username) ) {
      $_.Computer = $computers[$_.Username]
    }
    if ( $netDrives.ContainsKey($_.Username) ) {
      $_.NetworkDrives = $netDrives[$_.Username]
    }
    $_
  } | Export-Csv -NoTypeInformation .\output.csv

【讨论】:

  • Ansgar,你能解释一下这部分代码的作用吗? @{n='计算机';e={}},@{n='NetworkDrives';e={}} `
  • 那些是空的calculated properties。他们将缺少的字段 ComputerNetworkDrives 添加到来自 Huge.csv 的记录中,但没有分配值(还)。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-11-08
  • 1970-01-01
  • 2018-11-29
  • 1970-01-01
  • 1970-01-01
  • 2022-11-22
  • 2016-05-01
相关资源
最近更新 更多