'For-each file replace string based on a CSV Dictionary (Powershell)?

Working to configure a conversion script where replacements are done in files based on what is in the CSV file. Like a dictionary or lookup, rather than directly storing in the code.

i.e. File1.txt

Jim
Tim
Jan
Greg
Mark

CSV File

DEV,UAT,PROD
John,Jimothy,Timothy
Jimothy,Frank,Karen
Jim,Max,Lisa

So if converting DEV > UAT file1.txt would replace Jim with Max:

Max
Tim
Jan
Greg
Mark

Below is where I'm at currently convertReferences.ps1

#Declare Function Library
. $PSScriptRoot\functionLibrary.ps1
#Get Variables
$global:Dictionary = Import-Csv -Path $PSScriptRoot\IDDictionary.csv
#Input Location
$InputLocation = Read-Host 'Enter Input Location' ['DEV/UAT']
    If(!(test-path $PSScriptRoot\$InputLocation))
        {
        New-Item -ItemType Directory -Force -Path $PSScriptRoot\$InputLocation
        }
#Get Output Location
$OutLocation = Read-Host 'Enter an Output Location' ['UAT/PROD']
    
        If(!(test-path $PSScriptRoot\$OutLocation))
        {
         New-Item -ItemType Directory -Force -Path $PSScriptRoot\$OutLocation
        }

#Call Function Convert-DEV
if ($InputLocation -eq 'DEV'){
$Files | convert-DEV -InputLocation $InputLocation -OutLocation $OutLocation}

else {Write-host "NO VALID INPUT DECLARED - PLEASE RUN AGAIN" -ForegroundColor RED
    <# Action when all if and elseif conditions are false #>
}

The Function itself is below:

function convert-DEV {
[cmdletbinding()]
param(
    #Input Path
    [Parameter(Mandatory)]
    [ValidateSet('DEV')]
    [string]
    $InputLocation,

    #Files
    [Parameter(Mandatory, ValueFromPipeline)]
    [string]
    $Files,

    #Output Path
    [parameter()]
    [ValidateSet('UAT')]
    [string]
    $OutLocation
)
process{
        Write-host "Replacing Variables in: " $Files -ForegroundColor Blue
        $Staging = $Files
        (Get-Content $Files | foreach {$_ -replace $Global:Dictionary.DEV , $Global:Dictionary.UAT}) |
        Set-Content $Files
        (Get-Content $Staging | foreach {Copy-Item -Path $Staging -Destination $PSScriptRoot\$OutLocation})
        Write-host "UPDATED File has been copied to: " -ForegroundColor Red $PSScriptRoot\$OutLocation `n `n
} 
}

Any thoughts on how to reach my desired output?



Solution 1:[1]

You can use this function to get you started, this is assuming the CSV and the File are placed in the same location:

$csv = Import-Csv .\ReferenceTable.csv

function Replace {
    [cmdletbinding()]
    param(
        [Parameter(Mandatory, ValueFromPipeline)]
        [string] $File,

        [Parameter(Mandatory)]
        [ValidateSet('DEV', 'UAT', 'PROD')]
        [string] $InputLocation,

        [Parameter(Mandatory)]
        [ValidateSet('DEV', 'UAT', 'PROD')]
        [string] $OutLocation,

        [Parameter(Mandatory)]
        [object[]] $ReferenceTable
    )

    begin {
        $map = @{}
        foreach($i in $ReferenceTable) {
            $map[$i.$InputLocation] = $i.$OutLocation
        }
    }
    process {
        foreach($line in (Get-Content $File).Trim()) {
            if($map.ContainsKey($line)) {
                $map[$line]
                continue
            }
            $line
        }
    }
}

Get-ChildItem .\File1.txt | Replace -InputLocation DEV -OutLocation UAT -ReferenceTable $csv

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Santiago Squarzon