将结果从“比较对象”添加到数组

时间:2018-12-20 15:03:04

标签: powershell csv compareobject

我正在比较两个文件,一个是CSV文件,一个是txt文件。 CSV文件包含大约5,000个服务器的信息,而txt文件仅包含大约3,000个服务器的服务器名称。 CSV内的列是名称,操作系统和类型。这是我比较对象的步骤:

$compareObject = Compare-Object -ReferenceObject $txtFile -DifferenceObject $csvFile.Name -IncludeEqual

在此之后,我得到了三个选择。在两个列表==上的一个,仅在txt文件=>上的一个,以及仅在csv文件=<上的一个。

我想做的是将.SideIndicator取为等于==的值,并将其作为$csvFile内的一列,这样我最终可以做{{1} }

所以基本上我想弄清楚怎么写:

If ($csvFile.SideIndicator -eq "==")...

我尝试在脚本中当前放置If (($csvFile.Name -like $compareObject.InputObject) -and ($compareObject.InputObject -eq "==") { (add .SideIndicator to CSV file) } 的位置放置变量$count++,以查看返回多少结果,并且该结果始终返回0。

有人可以帮我解决这个问题或给我一些想法吗?

3 个答案:

答案 0 :(得分:3)

您希望通过管道传递Compare-Object的结果来终止对SideIndicator的过滤,如下所示:

$fields = "name", "street", "zip", "city"
Compare-Object -ReferenceObject $txtFile -DifferenceObject $csvFile.Name -IncludeEqual -Property $fields -PassThru | Where-Object {
    $_.SideIndicator -eq "=="
} | Select-Object $fields | Export-Csv ".\output.csv" -NoTypeInformation

$fields包含您的CSV标头

答案 1 :(得分:3)

这可能太复杂了,但是您可以进行以下操作:

假设这是您的CSV文件:

"Name","OS","Type"
"htew804","Windows","WindowsAutherServer"
"wddg9028","Windows","WindowsAutherServer"
"other321","Windows","WindowsBackupServer"

这是文本文件的内容:

wddg9028
test1234
htew804

然后输入此代码:

$csvFile = 'D:\blah.csv'
$txtFile = 'D:\names.txt'

# import the .csv file
$csv = Import-Csv -Path $csvFile
# read the .txt file which contains only server names, each on a separate line
$txt = Get-Content -Path $txtFile

$items = Compare-Object -ReferenceObject $txt -DifferenceObject $csv.Name -IncludeEqual -PassThru 
$result = foreach ($item in $items) {
    $name = $item.ToString()
    switch ($item.SideIndicator) {
        '<='  { 
            # the servername is only present in the text file
            [PSCustomObject]@{
                Name = $name
                OS = ''
                Type = ''
                SideIndicator = $item.SideIndicator
                Comment = "Name only found in $txtFile"
            }
            break
        }
        default  { 
            # '==' AND '=>': the servername is only present in the csv file or in both files
            $server = @($csv | Where-Object { $_.Name -eq $name })[0]
            [PSCustomObject]@{
                Name = $server.Name
                OS = $server.OS
                Type = $server.Type
                SideIndicator = $item.SideIndicator
                Comment = if ($item.SideIndicator -eq '==') { "Name found in both files" } else { "Name only found in $csvFile" }
            }
        }
    }
}
$result | Format-Table -AutoSize

产生以下结果:

Name     OS      Type                SideIndicator Comment                        
----     --      ----                ------------- -------                        
wddg9028 Windows WindowsAutherServer ==            Name found in both files       
htew804  Windows WindowsAutherServer ==            Name found in both files       
other321 Windows WindowsBackupServer =>            Name only found in D:\blah.csv 
test1234                             <=            Name only found in D:\names.txt

如果您希望将此信息写入新的CSV文件,请将Format-Table -AutoSize更改为Export-Csv -Path 'D:\blah_updated.csv' -NoTypeInformation

答案 2 :(得分:3)

  • 获取Theo的示例文件,但同时导入两个文件(带有-Header Name的文本文件)
  • Razorfen-PassThru方法,
  • 加上颠倒顺序将csv文件设置为-Reference

就这么简单:

$csvFile = Import-Csv .\sample.csv
$txtFile = Import-csv .\sample.txt -Header Name

Compare-Object -Ref $csvFile -Dif $txtFile -Property Name -IncludeEqual -PassThru

获得此所需的输出:

Name     OS      Type                SideIndicator
----     --      ----                -------------
wddg9028 Windows WindowsAutherServer ==
htew804  Windows WindowsAutherServer ==
test1234                             =>
other321 Windows WindowsBackupServer <=

所以两个人都从我这里得到+1。