Powershell:将变量从一个CSV与另一个CSV进行比较,并根据该变量创建新变量

时间:2017-05-30 13:25:29

标签: powershell

有人要问的问题是编辑试用后方法

2 个答案:

答案 0 :(得分:3)

您的csv文件格式不正确,因此我无法确定这是否正是您所需要的,但这应该指向正确的方向:

$File1 = Import-Csv .\file1.csv -Delimiter "`t"
$File2 = Import-Csv .\file2.csv -Delimiter "`t"

$NewFile1 = $File1 | % {
    $Obj = [PSCustomObject]$_
    $Obj | Add-Member -Mem NoteProperty -Name Patched -Value ([bool]($_.CommanName -in $File2.CommanName))
    return $Obj
}

$NewFile1

将输出

Server   HotfixID CommanName      Patched
------   -------- ----------      -------
apdk778  kb3333   apdk778 kb3333     True
apdk778  yn2919   apdk778 yn2919     True
apdk778  lk4898   apdk778 lk4898     True
iijka211 kb3333   iijka211 kb3333   False
iijka211 yn2919   iijka211 yn2919    True
iijka211 lk4898   iijka211 lk4898    True

我用标签替换了前两组空格,以便读入csv文件。

答案 1 :(得分:1)

ConnorLSW's helpful answer效果很好,但您可以简化为定义计算属性的单个Select-Object调用,该调用也会表现得更好:

$file1Objects = Import-Csv .\file1.csv -Delimiter "`t"
$file2Objects = Import-Csv .\file2.csv -Delimiter "`t"

$decoratedFile1Objects = $file1Objects | Select-Object *,
  @{ n='Patched'; e={ ('No', 'Yes')[$file2Objects.CommanName -contains $_.CommanName] } }

Get-Help -Detailed Select-Object简要介绍了计算属性的工作原理;有关更详细的说明,请参阅我的this answer

注意使用成语(<choice-A>, <choice-B>)[<Boolean-Test>]根据布尔测试的结果选择两个选项中的一个:

  • ('No', 'Yes')是一个字符串数组,其元素为No(索引0)和Yes(索引1)。< / LI>
  • $file2Objects.CommanName -contains $_.CommanName是一个布尔表达式,当在数组 index [...])的上下文中使用时,会被强制转换为0(如果{{ 1}})或$False(如果1)。
  • 换句话说:

    • 如果布尔表达式返回$True,则使用索引$False,从而生成字符串0
    • 如果布尔表达式返回No,则使用索引$True,从而生成字符串1
  • 请注意,此方法是解决方法,因为PowerShell缺少三元条件,其他语言(如C#)具有分支顺序指定是颠倒

    • C#伪代码:Yes
    • PowerShell解决方法:<Boolean-Test> ? "Yes" : "No"
    • 除了分支/选择的顺序之外,还有另一个重要的区别:如果您的数组元素是命令/表达式,它们全部评估,无论哪一个被选中(没有短路)。
    • 有一个杰出的feature request for ternary conditionals

至于您尝试的内容

您的嵌套('No', 'Yes')[<Boolean-Test>] - 循环方法:

  • 不为 un -patched rows
  • 创建输出对象
  • ,对于已修补的行,创建一个新对象,其属性是新对象。

以下代码修复了这些问题,再次依赖foreach添加新属性:

Select-Object

但是,使用PowerShell的$decoratedFile1Objects = foreach ($f1 in $file1) { # Add property and default to 'No' $f1Decorated = Select-Object -InputObject $f1 *, @{ n='Patched'; e={ 'No' } } foreach($f2 in $file2) { if ($f1.CommanName -eq $f2.CommanName) { # Match found: set property to 'Yes' and exit the inner loop $f1Decorated.Patched = 'Yes' break } } $f1Decorated # Output the decorated object. } -contains数组成员资格测试运算符不仅更方便,而且性能更佳。