'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 |
