0

我有两个文件正在比较,一个是 CSV,一个是 txt 文件。CSV 文件包含大约 5,000 个服务器的信息,而 txt 文件只有大约 3,000 个服务器名称。CSV 中的列是名称、操作系统和类型。这是我为比较对象所做的:

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

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

我想要做的是取.SideIndicatorfor 等于的值,==并将其作为一列放在里面,$csvFile这样我最终可以做If ($csvFile.SideIndicator -eq "==")...

所以基本上我想弄清楚如何写:

If (($csvFile.Name -like $compareObject.InputObject) -and ($compareObject.InputObject -eq "==") {
    (add .SideIndicator to CSV file)
}

我尝试在脚本中$count++当前拥有的位置放置一个变量,add .SideIndicator...以查看返回了多少结果,并且它始终返回 0。

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

4

3 回答 3

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-Headers

于 2018-12-20T15:14:25.190 回答
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

于 2018-12-20T16:16:27.850 回答
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。

于 2018-12-20T16:55:18.710 回答