Powershell - 根据多个字段标准删除CSV中的特定重复项/一式三份

时间:2016-02-01 06:50:13

标签: csv powershell duplicates

我有一份工作,从多个服务器收集操作系统信息。生成了几个包含Servername,OSCaption,OSversion的CSV文件(本例简化)。如果服务器可访问,则OSCaption和OSVersion字段将被正确填充。如果没有,则在输出文件的OSCaption字段中填充错误消息,另一个字段(OSVersion)保持为空。作业在不同的凭据下运行多次,以收集尽可能多的操作系统信息。最后我结合了CSV&s;我需要一种方法来删除某种类型的重复/一式三份等。我想保留一个具有良好操作系统字段的servername的单个实例,删除任何记录的相同的servername有错误但我也想在OSCaption中保留错误消息的任何单个实例,如果服务器完全无法访问的话。

我有一个未分类的CSV输入文件,如下所示:

Servername,OSCaption,OSVersion
Server1,Microsoft Windows Server 2008 R2 Enterprise ,6.1.7601
Server2,Access denied,
Server2,Microsoft Windows Server 2008 R2 Enterprise ,6.1.7601
Server3,RDP Error,
Server4,Microsoft Windows Server 2008 R2 Enterprise ,6.1.7601
Server2,Access Denied,
Server5 Access Denied,

您可以看到Server2在三个凭据下运行,第二个凭证有效。我想丢弃Server2的两个错误记录。我需要输出CSV看起来像这样:

Servername,OSCaption,OSVersion
Server1,Microsoft Windows Server 2008 R2 Enterprise ,6.1.7601
Server2,Microsoft Windows Server 2008 R2 Enterprise ,6.1.7601
Server3,RDP Error,
Server4,Microsoft Windows Server 2008 R2 Enterprise ,6.1.7601
Server5 Access Denied,

我仍然想要Server3和Server5的错误记录,但没有任何好的可用OSCaption,OSversion条目。

以下是我在其他帖子中播放的一些代码

#http://stackoverflow.com/questions/28170660/delete-duplicate-strings-in-csv-using-powershell


$scrubbed = @()
$data = import-csv C:\posh\duptest.csv #| sort Servername,OSversion 

$data | ForEach-Object{
    If($scrubbed.servername -contains $_.servername){
    # We already have this Num1 check to see if it is null
    If($_.osversion){
        # Num3 is populated so it can be added. 
        $scrubbed += $_
        }
    } Else {
        # This Num1 is unique and should be added. 
        $scrubbed += $_
    }
}

# Output to file
$scrubbed | Export-Csv "C:\posh\scrubbed.csv" -NoTypeInformation

ii "C:\posh\scrubbed.csv"

似乎无法处理三个相同的服务器名,留下两个server2记录。除了在后续输出文件上多次重新运行之外,还有更优雅的方法吗? get-unique似乎没有做我想的那样。

3 个答案:

答案 0 :(得分:0)

假设您有以下CSV文件:

<强> test1.csv:

Computer Name,Msg 1,Msg 2
COMPUTER 1,Access Denied,
COMPUTER 2,Access Denied,
COMPUTER 3,Windows XP,Yet again another msg
COMPUTER 4,Windows 7,Message
COMPUTER 5,Access Denied,

<强> test2.csv:

$a = Import-Csv .\test1.csv
$b = Import-Csv .\test2.csv

首先,您需要导入您要处理的所有文件:

$c = $a + $b

在此之后,我们将所有输入组合成一个大数组来处理:

Group-Object

我们首先需要对“计算机名”列中的行进行分组。为此,我们使用$d = $c | Group-Object -Property "Computer Name" | % { $goodRow = $_.Group | ? { [string]::IsNullOrWhiteSpace($_.'msg 2') -ne $true } | Select -First 1 if ($goodRow -eq $null) { $_.Group | Select -First 1 } else { $goodRow } } cmdlet,使用“计算机名称”作为要分组的属性名称。

这将为我们提供一个包含两个属性的数组。第一个属性是“计算机名”字段。第二个字段是原始数组中具有特定“计算机名”的行数组。

这意味着我们可以从这个“内部数组”中选择最合适的行。最合适的行是具有非空第3列或第1行失败的第一行。

$d

我们现在在变量Export-Csv中拥有了我们想要的内容,并使用$d | Export-Csv .\test3.csv 将其保存到新文件中。

if text.characters.count == 0 { // if backspace
    return true
}

if (self.txtv.text.characters.count) >= 50 {
     return false
    }
    return true
}

答案 1 :(得分:0)

关于您的特定CSV示例,并假设仅在没有错误时填充OSVersion列,您可以尝试这种方法:

$Array = @()
$csv = Import-Csv C:\temp.csv
$group = $csv | group servername
foreach ($item in $group)
{
    if ($item.Count -eq 1)
    {
    $Array += $item.Group
    }

        else
        {
        $array += $item.Group | ? {$_.OSVersion}
        }
}

$Array结果:

Servername OSCaption                                    OSVersion
---------- ---------                                    ---------
Server1    Microsoft Windows Server 2008 R2 Enterprise  6.1.7601 
Server2    Microsoft Windows Server 2008 R2 Enterprise  6.1.7601 
Server3    RDP Error                                             
Server4    Microsoft Windows Server 2008 R2 Enterprise  6.1.7601 
Server5    Access Denied 

<强> BUT: 如果你的服务器(例如Server6)只有错误,你将根本看不到该服务器的结果,为了解决这个问题,用这个替换else部分:

 else
    {
        if ($item.Group.OSVersion -match '\d')
        {
        $array += $item.Group | ? {$_.OSVersion}
        }
            else
            {
            $Row = "" | Select Servername,OSCaption,OSVersion
            $Row.Servername = $item.Group[0].Servername
            $Row.OSCaption = $item.Group.OSCaption -join ','
            $array += $Row
            }
    }

结果将是:

Servername OSCaption                                    OSVersion
---------- ---------                                    ---------
Server1    Microsoft Windows Server 2008 R2 Enterprise  6.1.7601 
Server2    Microsoft Windows Server 2008 R2 Enterprise  6.1.7601 
Server3    RDP Error                                             
Server4    Microsoft Windows Server 2008 R2 Enterprise  6.1.7601 
Server5    Access Denied                                         
Server6    RDP Error,Access Denied,RDP Error                     

答案 2 :(得分:0)

发布的解决方案看起来不错。只是想提供另一种选择:

这假设对于那些出现错误的服务器,osversion列值将为空白。

Deskriptive Statistik                   
        N   Minimum Maximum Mittelwert  Standardabweichung
x1kb    14  1,00    10,00   5,7857      2,63639
y1      8   777,00  777,00  777,0000    ,00000
Gültige Werte (Listenweise) 6