1

Sample of file names in our naming convention using PowerShell:

SYSTEM_20201019-01_PRE folder

  • SYSTEM_20201118_file1.txt
  • SYSTEM_20201118_file2.csv
  • SYSTEM_20201118_file3_and_file4.txt

SYSTEM_20201019-01_POST folder

  • SYSTEM_20201119_file1.txt
  • SYSTEM_20201119_file2.csv
  • SYSTEM_20201119_file3_and_file4.txt

We use this convention and it worked well as simply "SYSTEM_file1.txt" before we added the date. If we include the date in there, our script will only compare them if the date matches (which makes sense). This works mostly because the filenames are typically the same in the before and after. However, sometimes the dates will change and we simply have to manually rename all the files in the before, and then it works properly. We want to alleviate this manual work for others.

Is there a way I can take the PRE and POST and redefine them parsing out the first XX characters to only compare based on the name after the second _ character? The filenames, filename lengths, and extensions vary so I need to start from the beginning and not the end.

Here's the full code:

if($changeStatus -eq "POST"){

Write-Host "`n`n*********************************************"
Write-Host "`nComparing all PRE/POST files for differences."

$folderPath = $changeID + "_" + $env:COMPUTERNAME + "_"
$postFolderPath = $folderPath + "POST"
$preFolderPath = $folderPath + "PRE"
$comparisonFile = "$postFolderPath\Output_Comparison.txt"

if(!(Test-Path $preFolderPath)){
Write-Host "Missing PRE folder with the associated ChangeID. Unable to perform comparison."
Write-Host "Press any key to exit......"
Read-Host
exit
}

else{

$fileName = Get-ChildItem -Path $postFolderPath | Select-Object -ExpandProperty Name

ForEach ($file in $fileName){

$preFile = Get-Content ($preFolderPath + "\" + $file)
$postFile = Get-Content ($postFolderPath + "\" + $file)
$comparisonOutput = Compare-Object $preFile $postFile | Where-Object {($_.SideIndicator -eq "=>") -and (($_.InputObject -replace '"',"") -ne $dateRan)}  | Select-Object -ExpandProperty InputObject

if($comparisonOutput -ne $null){
    if(Test-Path $comparisonFile){
        "`r`n`r`nDifference in file $file" | Add-Content -Path $comparisonFile
        $comparisonOutput | Add-Content -Path $comparisonFile
    }

    else{
        "The following are the diffences found in POST files:" | Out-File -FilePath $comparisonFile
        "`r`nDifference in file $file" | Add-Content -Path $comparisonFile
        $comparisonOutput | Add-Content -Path $comparisonFile

    }
}

}


} 


}

5
  • 1
    Welcome to superuser. I'm sure a powershell expert will chime in soon, but in the meantime, try searching for "regular expressions". Commented Nov 19, 2020 at 0:51
  • where is the code you are discussing? what is in $before, $after, and $SYSTEM.Length? ///// are you limited to ps3? if so, what operating system are you running?
    – Lee_Dailey
    Commented Nov 19, 2020 at 5:18
  • How to ask If this is your file taxonomy [SYSTEM_20201118_file1.txt], then length really does not matter. You can just split on the underscore '_', change it to whatever, then join the string back to build your new name to use, or just match the target string and replace it using RegEx.
    – postanote
    Commented Nov 19, 2020 at 16:25
  • @Lee_Dailey - We are running mostly Windows 10 and Windows Server 2012 R2. Some are going to be transitioned over to Server 2016 or 2019 in the near future though.
    – Cory
    Commented Nov 19, 2020 at 22:51
  • @Porcupine911 Thanks for the insights. I'm still learning how to do regular expressions, so this is helping out a bit also.
    – Cory
    Commented Nov 19, 2020 at 22:54

1 Answer 1

0

You are not showing any code, and you should, in order to avoid assumptions and guessing from us and better get guidance from us here; but if I get your use case, there are several ways to address this.

# Break the string into an array
'SYSTEM_20201118_file1.txt'.Split('_')
# Results
<#
SYSTEM
20201118
file1.txt
#>

# Grab the first array item and change it, then join them back together
'SYSTEM_20201118_file1.txt'.Split('_')[0]
# Results
<#
SYSTEM
#>

# Or just replace a specific string
'SYSTEM_20201118_file1.txt' -replace 'SY','SX'
# Results
<#
SXSTEM_20201118_file1.txt
#>

Update as per your stated comment below

Refactor without using split but regex instead.

Clear-Host
(Get-ChildItem -Path 'D:\Temp' -Filter 'System_*').FullName
# Results
<#
D:\Temp\SYSTEM_20201119_file1.txt
D:\Temp\SYSTEM_20201119_file2.csv
D:\Temp\SYSTEM_20201119_file3_and_file4.txt
#>

Clear-Host
Get-ChildItem -Path 'D:\Temp' -Filter 'System_*' |
# Use regex to get the last the string after the last underscore 
ForEach-Object {[regex]::Matches($PSItem.BaseName, '[^_]+$').Value}
# Results
<#
file1
file2
file4
#>

Then do as you wish with those results.

4
  • I think I can get more details to test from here. I'm looking to pull only the file1.txt out of each filename and then do a comparison using only the last portion of the array. If I split it out as you suggested, then called the array[2] that should get me only the 3rd portion only as I wanted. Working on getting the code right to do that now.
    – Cory
    Commented Nov 19, 2020 at 22:52
  • Good to know this gave you some more ideas to run with.
    – postanote
    Commented Nov 19, 2020 at 23:20
  • I'm not trying to find out how to finish off the array to the end. The middle results with the returning SYSTEM is closest. Now when I change the array to 2 it returns the file1.txt which is what we need. The problem is that some files have longer names and underscores in their names. How do I get that array you listed - 'SYSTEM_20201118_file1.txt'.Split('')[2] - to go from starting at character 2 all the way to the end of the input? If I run this - 'SYSTEM_20201118_file3_and_file4.txt'.Split('')[2] - I only get the results of "file3" but I want from file3 to the end of the input.
    – Cory
    Commented Nov 20, 2020 at 1:29
  • Still do the same split and to get the last item after the last underscore, use [-1]. See my update for you.
    – postanote
    Commented Nov 20, 2020 at 3:46

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .