Search code examples
regexpowershelltext

Powershell script using RegEx to look for a pattern in one .txt and find line in a second .txt


I have a real "headsmasher" on my plate.

I have this piece of script:

$lines = Select-String -List -Path $sourceFile -Pattern $pattern -Context 20

foreach ($id in $lines) {

    if (Select-String -Quiet -LiteralPath export.txt -Pattern "$($Matches[1]).+$($id.Pattern)") {

        }

    else {
    
        Select-String -Path $sourceFile -Pattern $pattern -Context 20 >> $duplicateTransactionsFile
    
        }
    }

but it is not working for me as I wanted it to.

I have two .txt files: "$sourcefile = source.txt" and "export.txt"

The source.txt looks like something like this:

Some text here ***********
------------------------------------------------
 F I N A L  C O U N T                  1 9 , 9 9

**************
** [0000123456]
ID Number:0000123456
Complete!
****************!
***********



Some other text here*******
------------------------------------------------
 F I N A L  C O U N T                    9 , 9 9

**********
** [0000789000]
ID Number:0000789000
Complete!
******************!
************

The export.txt is like this:

0000123456  19,99
0000555555  ,89
0000666666  3,05
0000777777  31,19
0000789000  9,99

What I am trying to do is look into source.txt and search for the number that I enter (spaced out in my case)

*e.g: "9,99" but only that. As you can see, the next number in the source.txt is "19,99" and it also contains "9,99" but I do not want it to be matched.

and once I find the number, look for the next line in the source.txt that contains the text "ID Number:" then get the numbers right after the ":" Once I get those numbers after the ":", I want to now look into the export.txt and see if the numbers after the ":" are there and whether it has the "9,99" on the same line next to it but exactly "9,99" and nothing else lie "19,99", "29,99", and so on.

Then the rest is easy:

if (*true*) {
do this
}

else {
do that
}

Could you guys give me some love here and help a brother out? I very much appreciate any help or hint you could share.

Best of wishes!


Solution

  • You could approach this like below:

    # read the export.txt file and convert to a Hashtable for fast lookup
    $export = ((Get-Content -Path 'D:\Test\export.txt').Trim() -replace '\s+', '=') -join "`r`n" | ConvertFrom-StringData
    
    # read the source file and split into multiline data blocks
    $source = ((Get-Content -Path 'D:\Test\source.txt' -Raw) -split '-{2,}').Trim() | Where-Object { $_ -match '(?sm)^\s?F I N A L  C O U N T' }
    
    # make sure the number given is spaced-out
    $search = (((Read-Host "Search for Final Count number") -replace '\s' -split '') -join ' ').Trim()
    Write-Host "Looking for a matching item using Final Count '$search'"
    
    # see if we can find a data block that matches the $search
    $blocks = $source | Where-Object { $_ -match "(?sm)^F I N A L  C O U N T\s+$search\s?$" }
    if (!$blocks) {
        Write-Host "No item in source.txt could be found with Final Count '$search'" -ForegroundColor Red
    }
    else {
        # loop over the data block(s) and pick the one that matches the search count
        $blocks | ForEach-Object {
            # parse out the ID
            $id = $_ -replace '(?sm).*ID Number:(\d+).*', '$1'
            # check if the $export Hashtable contains a key with that ID number
            if ($export.Contains($id)) {
                # check if that item has a value of $search without the spaces
                if ($export[$id] -eq ($search -replace '\s')) {
                    # found it; do something
                    Write-Host "Found a match in the export.txt" -ForegroundColor Green
                }
                else {
                    # found ID with different FinalCount
                    Write-Host "An item with ID '$id' was found, but with different Final Count ($($export[$id]))" -ForegroundColor Red
                }
            }
            else {
                # ID not found
                Write-Host "No item with ID '$id' could be found in the export.txt" -ForegroundColor Red
            }
        }
    }
    

    If as per your comment, you would like the code to loop over the Final Count numbers found in the source.txt file instead of a user typing in a number to search for, you can shorten the above code to:

    # read the export.txt file and convert to a Hashtable for fast lookup
    $export = ((Get-Content -Path 'D:\Test\export.txt').Trim() -replace '\s+', '=') -join "`r`n" | ConvertFrom-StringData
    
    # read the source file and split into multiline data blocks
    $blocks = ((Get-Content -Path 'D:\Test\source.txt' -Raw) -split '-{2,}').Trim() | 
                Where-Object { $_ -match '(?sm)^\s?F I N A L  C O U N T' }
    
    if (!$blocks) {
        Write-Host "No item in source.txt could be found with Final Count '$search'" -ForegroundColor Red
    }
    else {
        # loop over the data block(s)
        $blocks | ForEach-Object {
            # parse out the FINAL COUNT number to look for in the export.txt
            $search = ([regex]'(?sm)^F I N A L  C O U N T\s+([\d,\s]+)$').Match($_).Groups[1].Value
            # remove the spaces, surrounding '0' and trailing comma (if any)
            $search = ($search -replace '\s').Trim('0').TrimEnd(',')
            Write-Host "Looking for a matching item using Final Count '$search'"
            # parse out the ID
            $id = $_ -replace '(?sm).*ID Number:(\d+).*', '$1'
            # check if the $export Hashtable contains a key with that ID number
            if ($export.Contains($id)) {
                # check if that item has a value of $search without the spaces
                if ($export[$id] -eq $search) {
                    # found it; do something
                    Write-Host "Found a match in the export.txt with ID: $($export[$id])" -ForegroundColor Green
                }
                else {
                    # found ID with different FinalCount
                    Write-Host "An item with ID '$id' was found, but with different Final Count ($($export[$id]))" -ForegroundColor Red
                }
            }
            else {
                # ID not found
                Write-Host "No item with ID '$id' could be found in the export.txt" -ForegroundColor Red
            }
        }
    }