1

I am comparing two text files and sending the difference to an output file. Here is my simple code.

$file1 = (Get-Content .\txt1.txt)
$file2 = (Get-Content .\txt2.txt)
compare-object $file1 $file2 | out-file txt3.txt

(Get-Content -Path .\txt3.txt) |
    ForEach-Object {
        $_ -Replace '=>', 'After'`
           -Replace '<=', 'Before'`
    } |
        Set-Content -Path .\txt3.txt
Get-Content -Path .\txt3.txt

Now here is the output.

InputObject SideIndicator
----------- -------------
banaple     After           
cherry      After           
orange      Before           
strawberry  Before

Is it possible to alternate After and Before so that it would be easier for the user to understand this result? My main concern is if I have difference for a lot of lines and they are displayed like this, all After's on top followed by their corresponding Before's underneath, then it might cause confusion to the user. Or if I can put numbers beside them to point which After and Before are partners.

I hope someone could help me out with this. I'm just starting to familiarize myself with the Compare-Object command but I'm really having a hard time getting the modifications I need. I thank in advance whoever will have the answer for my question :)

Abraham Zinala
  • 4,267
  • 3
  • 9
  • 24
  • 1
    Is this a line by line comparison? What would be your expected output? – Santiago Squarzon Jul 19 '21 at 01:20
  • 1
    What do you mean by *alternate*? Can you show us how you would like the output to be shown. – Abraham Zinala Jul 19 '21 at 01:21
  • It is by line comparison, yes. And by alternate I mean After-Before, not After-After, Before-Before. I'm sorry I sound like a total dumdum but I guess my ideal output is this: InputObject SideIndicator ----------- ------------- banaple After orange Before cherry After strawberry Before – user16437525 Jul 19 '21 at 01:26
  • If before could come first it would be much better. I'm sorry my previous comment would've been better if it's in tabular form but yeah, that's pretty much the output I'm aiming for. – user16437525 Jul 19 '21 at 01:28

1 Answers1

1

If you're comparing both files by their index, meaning, comparing index 0 on file1 with index 0 on file2 and son on I would personally not use Compare-Object at all since it's pretty slow:

$arr1 = 'orange','strawberry','orange'
$arr2 = 'banaple','cherry','orange','banana'

# Note: I'm placing those 2 arrays for demonstration purposes only.
# $arr1 and $arr2 should be changed to:
# $arr1 = Get-Content .\txt1.txt
# $arr2 = Get-Content .\txt2.txt

$totalCount = ($arr1.Count, $arr2.Count | Measure-Object -Maximum).Maximum

$arr3 = for($i=0;$i -lt $totalCount;$i++)
{
    $status = 'NO CHANGE'

    if($arr1[$i] -ne $arr2[$i])
    {
        $status = 'UPDATED'
    }

    [pscustomobject]@{
        Before = $arr1[$i]
        After = $arr2[$i]
        Status = $status
    }
}
  • $arr3 would result in the following:
Before     After   Status   
------     -----   ------   
orange     banaple UPDATED  
strawberry cherry  UPDATED  
orange     orange  NO CHANGE
           banana  UPDATED 
  • If you want to export $arr3 I would recommend you to use CSV as export format:
$arr3 | Export-Csv absolultepath\to\file3.csv -NoTypeInformation
  • If you want to export as a normal text file:
$arr3 | Out-File absolultepath\to\file3.txt

Same logic but as a function:

function Compare-Files {
[cmdletbinding()]
param(
    [parameter(mandatory)]
    [ValidateScript({Test-Path $_ -PathType Leaf})]
    [System.IO.FileInfo]$BeforeFile,
    [parameter(mandatory)]
    [ValidateScript({Test-Path $_ -PathType Leaf})]
    [System.IO.FileInfo]$AfterFile
)

    $file1 = Get-Content $BeforeFile
    $file2 = Get-Content $AfterFile

    $totalCount = ($file1.Count, $file2.Count | Measure-Object -Maximum).Maximum
  
    for($i=0;$i -lt $totalCount;$i++)
    {
        $status = 'NO CHANGE'

        if($file1[$i] -ne $file2[$i])
        {
            $status = 'UPDATED'
        }

        [pscustomobject]@{
            Before = $file1[$i]
            After = $file2[$i]
            Status = $status
        }
    }
}

Demo:

PS /> Compare-Files -BeforeFile .\file1.txt -AfterFile .\file2.txt

Before     After   Status   
------     -----   ------   
orange     banaple UPDATED  
strawberry cherry  UPDATED  
orange     orange  NO CHANGE
           banana  UPDATED  

PS /> Compare-Files -BeforeFile .\file1.txt -AfterFile .\file2.txt | Export-Csv ...
Santiago Squarzon
  • 41,465
  • 5
  • 14
  • 37
  • 1
    Wow this is actually great. Thanks. I'd like to try it out with the data I am actually working on, I put up that fruit list as an example. About that code you wrote, may I know how can I output that to a separate text file? – user16437525 Jul 19 '21 at 01:59
  • @user16437525 see my edit, I added some notes too. – Santiago Squarzon Jul 19 '21 at 02:01
  • 1
    It's works perfectly, thank you! One last thing though, what if I want to do the same process for multiple couple of files? Say, like, 7 more pairs of files that I need to compare doing the same process as we did with this one. Do you think I can just put in more variables in this single script or would you suggest I create separate PowerShell scripts that does the same thing but meant for comparing different set of files and just call them all together with a batch file. (I'm calling my ps1 files with a batch file btw) – user16437525 Jul 19 '21 at 02:17
  • @user16437525 you mean you want to compare 14 + these 2 files against each other or do you mean you want to compare compare these 2, and then 7 more pairs but just a 2 file comparison? hope it make sense – Santiago Squarzon Jul 19 '21 at 02:21
  • It makes perfect sense, lol. You were right on your second guess. 7 more pairs but just a 2 file comparison. – user16437525 Jul 19 '21 at 02:23
  • @user16437525 see my last edit, I made a function that you can reuse, you simply pass 2 file paths to the function (consider passing the absolute path to the files if you're not on the same directory as the files) and it will get you the same results as before which you can then export. Please, if the answer was useful to you consider [accepting it](https://meta.stackexchange.com/questions/5234/how-does-accepting-an-answer-work/5235#5235) as it may help others in the future. – Santiago Squarzon Jul 19 '21 at 02:46
  • 1
    You've been really helpful, thank you very much! This solved my problem. I really appreciate you taking your time to address my concern. If there is any way I can make it up to you please do let me know :) – user16437525 Jul 19 '21 at 03:41