首页 > 解决方案 > 检查一个值是否存在于一个 csv 文件中,并使用 Powershell 将静态文本添加到另一个 csv 字段

问题描述

我需要检查第一个 csv 文件中的列值是否存在于其他三个 csv 文件中的任何一个中,并按优先顺序将值返回到新的 csv 文件中。
因此,如果 allStaff.csv 中的用户名字段存在于 sessionVPNct.csv 文件的用户名列表中,请将静态文本作为“VPN”放入最终的 csv 文件中。如果不存在,请检查下一个 csv 文件:sessionCRXct.csv 然后放入静态文本'CRX',如果不检查最后一个 csv 文件:sessionTMSct.csv 然后放入静态文本:TM 如果不存在则放入静态文本' none' 到最终的 csv 文件中。我有四个 csv 文件,如下所示:

1. allStaff.csv
2.VPN.csv
3.CRX.csv
4.TMS.csv

我已将 csv 文件导入到变量中,如下所示:

$allUsers = Import-Csv -Path "C:\allStaff.csv"
$vpn = Import-Csv -Path "C:\VPN.csv" | Select-Object -ExpandProperty UserName
$crx = Import-Csv -Path "C:\CRX.csv" | Select-Object -ExpandProperty UserName
$tms = Import-Csv -Path "C:\TMS.csv" | Select-Object -ExpandProperty UserName

$allUsers 变量显示以下内容:

名字姓氏用户名位置区域
--------- -------- -------- -------- ----
乔博客 jbloggs 园丁维护
吉姆·史密斯 jsmith 会计 财务
Bob Seger bseger 人力资源顾问 人力资源
Adam Boson aboson 客户支持 IT
阿黛尔·布雷·阿布雷工资财务

$vpn 变量显示以下内容:

用户名
--------
博客
史密斯

$crx 变量显示以下内容:

用户名
--------
博客
史密斯
赛格

$tms 变量显示以下内容:

用户名
--------
博客
史密斯
赛格
玻色子

然后我有以下行来启动结果 csv 文件

$result = $allUsers | Select-Object *,ConnectionMethod

不太确定如何进行最终查询,我认为这应该是一个 if else 循环来遍历 $result 变量中的所有行,并检查其他 csv 是否存在用户名字段,然后返回静态文本。

$result | Export-Csv -Path "C:\allStaffConnections.csv"

这就是我需要显示最终 allStaffConnections.csv 文件的方式。

名字 姓氏 用户名 位置 区域 连接方法
--------- -------- -------- -------- ---- ------------- -
乔博客 jbloggs 园丁维护 VPN
吉姆·史密斯 jsmith 会计财务 VPN
Bob Seger bseger 人力资源顾问 人力资源 CRX
Adam Boson aboson 客户支持 IT TMS
Adele bree abree 工资财务 无

我是否使用以下代码走在正确的轨道上?

$allUsers = Import-Csv -Path "C:\allStaff.csv"
$vpn = Import-Csv -Path "C:\VPN.csv" | Select-Object -ExpandProperty UserName
$crx = Import-Csv -Path "C:\CRX.csv" | Select-Object -ExpandProperty UserName
$tms = Import-Csv -Path "C:\TMS.csv" | Select-Object -ExpandProperty UserName
$vpnText = 'VPN'
$crxText = 'CRX'
$txsText = 'TMS'
$noneText = 'none'

$allUsersExtended = $allUsers | Select-Object *,ConnectionMethod
$results = $allUsersExtended.ForEach(
    {
        if($vpn -Contains $PSItem.UserName) {
            # add $vpnText to ConnectionMethod column for that row in the $result
            $PSItem.ConnectionMethod = $vpnText
        }elseif($crx -Contains $PSItem.UserName) {
            # add $crxText to ConnectionMethod column for that row in the $result
            $PSItem.ConnectionMethod = $crxText
        }elseif($tms -Contains $PSItem.UserName) {
            # add $txsText to ConnectionMethod column for that row in the $result
            $PSItem.ConnectionMethod = $tmsText
        }else {
            # add $noneText to ConnectionMethod column for that row in the $result
            $PSItem.ConnectionMethod = $noteText
        }
    })
$results | Export-Csv -Path "C:\allStaffConnections.csv" -NoTypeInformation

这给了我一个空的 allStaffConnections.csv 文件。
我已经逐行运行了代码,并且可以达到:

$allUsersExtended = $allUsers | Select-Object *,ConnectionMethod

这给了我额外的列“ConnectionMethod”,但在运行循环之后,它给了我一个空的 allStaffConnections.csv 文件。

标签: powershellcsv

解决方案


这是完成这项工作的一种方法。[ grin ] 它假定您只想找到第一个连接类型。如果你想要所有这些[例如,JBloggs 列出了所有 3 种类型],你需要将它们连接起来。

它能做什么 ...

  • 当准备好使用真实数据时,假装读取 CSV 文件
    ,注释掉或删除整个#region/#endregion部分并使用Get-Content.
  • 遍历主集合
  • 使用一个开关来测试每个连接类型列表中的成员资格,
    这会在找到匹配项时断开开关,因为它假定您只需要第一个匹配项。如果您想要所有这些,那么您将需要累积它们而不是打破开关块。
  • $ConnectionType适当地 设置
  • 使用通配符属性选择器和计算属性 构建一个包含所有需要的属性的 PSCO,
    这可能会缩短。Select-Object
  • 将其发送到$Results集合
  • 在屏幕上显示
  • 将其保存为 CSV 文件

编码 ...

#region >>> fake reading in CSV files
#    in real life, use Import-CSV
$AllUsers = @'
FirstName, LastName, UserName, Position, Area
Joe, Bloggs, jbloggs, Gardener, Maintenance
Jim, Smith, jsmith, Accountant, Finance
Bob, Seger, bseger, HR Advisor, Human Resources
Adam, Boson, aboson, Customer Support, IT
Adele, bree, abree, Payroll, Finance
'@ | ConvertFrom-Csv

$Vpn = @'
UserName
jbloggs
jsmith
'@ | ConvertFrom-Csv

$Crx = @'
UserName
jbloggs
jsmith
bseger
'@ | ConvertFrom-Csv

$Tms = @'
UserName
jbloggs
jsmith
bseger
aboson
'@ | ConvertFrom-Csv
#endregion >>> fake reading in CSV files

$Results = foreach ($AU_Item in $AllUsers)
    {
    # this presumes you want only the 1st connection type found
    #     if you want all of them, then you will need to concatenate them
    switch ($AU_Item.UserName)
        {
        {$_ -in $Vpn.UserName}
            {
            $ConnectionType = 'VPN'
            break
            }
        {$_ -in $Crx.UserName}
            {
            $ConnectionType = 'CRX'
            break
            }
        {$_ -in $Tms.UserName}
            {
            $ConnectionType = 'TMS'
            break
            }
        default
            {
            $ConnectionType = 'None'
            }
        }

    [PSCustomObject]@{
        FirstName = $AU_Item.FirstName
        LastName = $AU_Item.LastName
        UserName = $AU_Item.UserName
        Position = $AU_Item.Position
        Area = $AU_Item.Area
        ConnectionTYpe = $ConnectionType
        }
    }

# on screen
$Results

# send to CSV
$Results |
    Export-Csv -LiteralPath "$env:TEMP\brokencrow_-_UserConnectionType.csv" -NoTypeInformation

在屏幕输出上截断...

FirstName      : Joe
LastName       : Bloggs
UserName       : jbloggs
Position       : Gardener
Area           : Maintenance
ConnectionTYpe : VPN

[*...snip...*] 

FirstName      : Adele
LastName       : bree
UserName       : abree
Position       : Payroll
Area           : Finance
ConnectionTYpe : None

CSV 文件内容来自brokencrow_-_UserConnectionType.csv...

"FirstName","LastName","UserName","Position","Area","ConnectionTYpe"
"Joe","Bloggs","jbloggs","Gardener","Maintenance","VPN"
"Jim","Smith","jsmith","Accountant","Finance","VPN"
"Bob","Seger","bseger","HR Advisor","Human Resources","CRX"
"Adam","Boson","aboson","Customer Support","IT","TMS"
"Adele","bree","abree","Payroll","Finance","None"

推荐阅读