MacieQ
MacieQ

Reputation: 33

powershell: replacing string using hash table

I have files which need to be modified according to mapping provided in CSV. I want to read each line of my txt file and depending if specified value exist I want to replace other strings in that line according to my CSV file (mapping). For that purpose I have used HashTable. Here is my ps script:

$file ="path\map.csv"
$mapping = Import-CSV $file -Encoding UTF8 -Delimiter ";"
$table = $mapping | Group-Object -AsHashTable -AsString -Property Name

$original_file = "path\input.txt"
$destination_file = "path\output.txt"
$content = Get-Content $original_file

foreach ($line in $content){
    foreach ($e in $table.GetEnumerator()) {
    if ($line -like "$($e.Name)") { 
    $line = $line -replace $e.Values.old_category, $e.Values.new_category
    $line = $line -replace $e.Values.old_type, $e.Values.new_type
    }
    }
}

Set-Content -Path $destination_file -Value $content

My map.csv looks as follows:

Name;new_category;new_type;old_category;old_type
alfa;new_category1;new_type1;old_category1;old_type1
beta;new_category2;new_type2;old_category2;old_type2
gamma;new_category3;new_type3;old_category3;old_type3

And my input.txt content is:

bla bla "bla"

buuu buuu 123456 "test"
"gamma" "old_category3" "old_type3"
alfa 

When I run this script it creates exactly the same output as initial file. Can someone tell me why it didn't change the line where "gamma" appears according to my mapping ?

Thanks in advance

Upvotes: 3

Views: 1888

Answers (1)

arco444
arco444

Reputation: 22821

Couple of things to change.

Firstly there is no need to change $mapping to a hash, Import-Csv already gives you an object array to work with.

Secondly, if you want to update the elements of $content, you need to use a for loop such that you can directly access modify them. Using a foreach creates a new variable in the pipeline and you were previously modifying it but then never writing it back to $content

Below should work:

$file ="map.csv"
$mapping = Import-CSV $file -Encoding UTF8 -Delimiter ";"

$original_file = "input.txt"
$destination_file = "output.txt"
$content = Get-Content $original_file

for($i=0; $i -lt $content.length; $i++) {
  foreach($map in $mapping) {
    if ($content[$i] -like "*$($map.Name)*") { 
      $content[$i] = $content[$i] -replace $map.old_category, $map.new_category
      $content[$i] = $content[$i] -replace $map.old_type, $map.new_type
    }
  }
}

Set-Content -Path $destination_file -Value $content

Upvotes: 1

Related Questions