【问题标题】:compare two csv using powershell and return matching and non-matching values使用 powershell 比较两个 csv 并返回匹配和不匹配的值
【发布时间】:2014-09-02 04:45:50
【问题描述】:

我有两个 csv 文件,我想检查 username.csv 中的用户是否与 userdata.csv 副本匹配
输出.csv。如果不匹配,则在 output.csv 中单独返回名称

例如:用户数据包含 3 列

UserName,column1,column2
Hari,abc,123
Raj,bca,789
Max,ghi,123
Arul,987,thr
Prasad,bxa,324

username.csv 包含用户名

Hari
Rajesh

Output.csv 应该包含

Hari,abc,123
Rajesh,NA,NA

如何实现这一点。谢谢

对不起。

$Path = "C:\PowerShell"
$UserList = Import-Csv -Path "$($path)\UserName.csv"
$UserData = Import-Csv -Path "$($path)\UserData.csv"

foreach ($User in $UserList)
{
    ForEach ($Data in $UserData)
    {
        If($User.Username -eq $Data.UserName)
        {
            # Process the data

            $Data
        }
    }
}

这只会返回匹配的值。我还需要在输出中添加不匹配的值 文件。谢谢。

【问题讨论】:

标签: powershell csv


【解决方案1】:

这样的事情会起作用:

$Path = "C:\PowerShell"
$UserList = Import-Csv -Path "$($path)\UserName.csv"
$UserData = Import-Csv -Path "$($path)\UserData.csv"
$UserOutput = @()

    ForEach ($name in $UserList)
    {

        $userMatch = $UserData | where {$_.UserName -eq $name.usernames}
        If($userMatch)
        {
            # Process the data

            $UserOutput += New-Object PsObject -Property @{UserName =$name.usernames;column1 =$userMatch.column1;column2 =$userMatch.column2}
        }
        else
        {
        $UserOutput += New-Object PsObject -Property @{UserName =$name.usernames;column1 ="NA";column2 ="NA"}
        }
    }
$UserOutput | ft

它遍历用户列表中的每个名称。第 9 行在 userdata CSV 中搜索匹配的用户名,如果找到匹配的用户名,则将该用户的用户数据添加到输出中,如果未找到匹配项,则将用户名添加到输出中,两列均带有 NA。

必须更改您的 userList csv:

usernames
Hari
Rajesh

预期输出:

UserName                          column1                           column2                         
--------                          -------                           -------                         
Hari                              abc                               123                             
Rajesh                            NA                                NA 

【讨论】:

  • 嗨 Dane,感谢您提供完美运行的脚本。但是为什么 if 和 elseif 在我发布的脚本中不起作用。它要么多次返回名称,要么返回长度。再次感谢您的光临。
  • 您的方法要求您检查每个用户名,并在每次匹配或不匹配时执行一些操作。我为列表中的每个用户发布的一个完整循环遍历数据 csv。然后只检查用户是否在循环中找到并相应地处理。它只是更有效
【解决方案2】:

我遇到过类似的情况,当当前记录是新记录或与以前的记录相比有任何更改时,我需要一个“更改的记录集合”来保存整个记录。这是我的代码:

# get current and previous CSV
$current = Import-Csv -Path $current_file
$previous = Import-Csv -Path $previous_file

# collection with new or changed records
$deltaCollection = New-Object Collections.Generic.List[System.Object]

:forEachCurrent foreach ($row in $current) {

  $previousRecord = $previous.Where( { $_.Id -eq $row.Id } )
  $hasPreviousRecord = ($null -ne $previousRecord -and $previousRecord.Count -eq 1)
  if ($hasPreviousRecord -eq $false) {
    $deltaCollection.Add($current)
    continue forEachCurrent
  }

  # check if value of any property is changed when compared to the previous 
  :forEachCurrentProperty foreach ($property in $current.PSObject.Properties) {

    $columnName = $property.Name

    $currentValue = if ($null -eq $property.Value) { "" } else { $property.Value } 
    $previousValue = if ($hasPreviousRecord) { $previousRecord[0]."$columnName" } else { "" }

    if ($currentValue -ne $previousValue -or $hasPreviousRecord -eq $false) {
      $deltaCollection.Add($currentCenter)
      continue forEachCurrentProperty
    }

  }

}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-02-21
    • 1970-01-01
    相关资源
    最近更新 更多