是否存在可以并行比较CSV的PowerShell脚本?

时间:2019-07-11 07:06:36

标签: powershell

我有两个CSV,其中包含通过运行查询填充的数据。我打算将两者进行比较,以了解使用Compare-Object cmdlet有什么区别。

CSV文件如下所示:

CSV1

TableName        ColumnName
------------------------------
Container        ContainerName
Container        Location
Container        ReceivedDate
Container        TopMark

CSV2

TableName        ColumnName
------------------------------
Container        Containername
Container        Location
Container        DateReceived
Container        BackMark

现在,我正在使用的Compare-Object cmdlet在PowerShell中很容易获得。它运行的很好,我正在获得想要的结果。但是,对于不知道如何读取Compare-Object cmdlet生成的结果的人来说,结果可能很难理解。我试图通过比较每个属性来简化结果,但是我的最终用户仍然不了解结果。我什至更改了SideIndicator,以注意“引用”或“差异”副本上是否存在对象。

$compareResult = (Compare-Object -ReferenceObject $file1 -DifferenceObject $file2 -Property TableName, ColumnName |
    ForEach-Object {
        $_.SideIndicator = $_.SideIndicator -replace '=>',$onlyD -replace '<=',$onlsyG
        $_
    })

他们想看到的是这样的:

LeftSideInputObject        RightSideInputObject
-----------------------------------------------
Container,ContainerName    Container,ContainerName
Container,Location         Container,Location
Container,ReceivedDate
                           ContainerDateReceived
Container,TopMark
                           Container,BackMark

有没有机会在PowerShell中执行此操作?谢谢!

2 个答案:

答案 0 :(得分:1)

您可以使用Select-Object创建自定义对象。

Compare-Object $file1 $file2 -Property TableName,ColumnName -IncludeEqual | Select-Object @(
    @{ n = "Left";   e = { if ($_.SideIndicator -in "==","<=") { $_.TableName,$_.ColumnName -join "," } } }
    @{ n = "Right";  e = { if ($_.SideIndicator -in "==","=>") { $_.TableName,$_.ColumnName -join "," } } }
)

答案 1 :(得分:1)

检查:

Add-Type -AssemblyName System.Collections

#-----------------------------------------------------
class comparerClass {   # class for result object
#-----------------------------------------------------

    comparerClass(
        [string]$leftSide,
        [string]$rightSide
    )
    {
        $this.leftSide  = $leftSide
        $this.rightSide = $rightSide
    }

    [string]$leftSide = ''
    [string]$rightSide = ''
}

# Collections: File1, File2 and result list

[System.Collections.Generic.List[string]]$contentFile1 = @()
[System.Collections.Generic.List[string]]$contentFile2 = @()
[System.Collections.Generic.List[comparerClass]]$comparerList= @()

# Files to process

$pathFile1  = 'D:\csv1.txt'
$pathFile2  = 'D:\csv2.txt'

# read files to generic lists

$contentFile1.AddRange( [System.IO.File]::ReadAllLines( $pathFile1 ) )
$contentFile2.AddRange( [System.IO.File]::ReadAllLines( $pathFile2 ) )

# pointer for generic lists

$ptrFile1 = 0
$ptrFile2 = 0

# process lists, mainloop

while( $ptrFile1 -lt $contentFile1.Count ) {

    # equal, easy is this
    if( $contentFile1[ $ptrFile1 ] -eq $contentFile2[ $ptrFile2 ] ) {
        $tmpComparer =  New-Object comparerClass -ArgumentList $contentFile1[ $ptrFile1 ], $contentFile2[ $ptrFile2 ]
        $comparerList.Add( $tmpComparer )
        $ptrFile1++
        $ptrFile2++
    }
    else {    # not equal, check if entry list 1 comes later in list 2
        $ptr   = $ptrFile2 + 1
        $found = $false
        while( $ptr -lt $contentFile2.Count ) {
            if( $contentFile1[ $ptrFile1 ] -eq $contentFile2[ $ptr ] ) {      # entry found later in list2!
                for( $i = $ptrFile2; $i -lt $ptr; $i++ ) {
                    $tmpComparer =  New-Object comparerClass -ArgumentList '', $contentFile2[ $i ] 
                    $comparerList.Add( $tmpComparer )
                }
                $ptrFile2 = $ptr + 1
                $found    = $true
                $ptrFile1++
                break
            }
            $ptr++
        }
        if( !$found ) {     # entry not found, this entry only exists in list1
            $tmpComparer =  New-Object comparerClass -ArgumentList $contentFile1[ $ptrFile1 ], ''
            $comparerList.Add( $tmpComparer )
            $ptrFile1++
        }
    }

}

# process remaining entries in list2
while( $ptrFile2 -lt $contentFile2.Count ) {
    $tmpComparer =  New-Object comparerClass -ArgumentList '', $contentFile2[ $ptrFile2 ] 
    $comparerList.Add( $tmpComparer )
    $ptrFile2++
}

# show result
$comparerList