Reputation: 25
I read a CSV file into an array of objects (using Import-Csv
). If I write that data back to disk with Export-Csv
, I get exactly what I expected, a well formatted CSV.
Now I need to change some data in that CSV. One of them being strings that need to be replaced. But if I do a simple:
$thisIsTheArrayOfObjects -replace "Old ID", "New ID"
it results in an array of STRINGS. (the replacement happened, but somehow all my objects in the array got casted to strings)
Of course now the Export-Csv
does not deliver the expected result. It's just exporting a file with all the length of the strings in my array.
How can I replace strings in properties of PSOBJECTS in an array?
Upvotes: 0
Views: 2510
Reputation: 338118
How can i replace strings in properties of PSOBJECTS in an array?
You do it for each object.
$thisIsTheArrayOfObjects | ForEach-Object {
$_.foo = $_.foo -replace "Old ID" , "New ID" # replace string in a property
$_ # output the object back onto the pipeline
}
Keep in mind that there are two gotchas with -replace
:
[regex]::escape("Old ID")
) if you want to do a literal replacement, unless "Old ID" does not contain any characters that are special in regex. If it comes from user input, it's always wise to escape it.To do case-sensitive, literal replacements, use the .NET-native String.Replace()
, which is also available:
$thisIsTheArrayOfObjects | ForEach-Object {
$_.foo = $_.foo.Replace("Old ID", "New ID") # replace string in a property
$_ # output the object back onto the pipeline
}
To apply an operation to every column in the CSV data, you have to create a nested loop. The Get-Member
cmdlet can help. The principle stays the same as above.
Import-Csv "input.csv" -PipelineVariable row | ForEach-Object {
$row | Get-Member -MemberType NoteProperty -PipelineVariable col | ForEach-Object {
$colname = $col.Name
$row.$colname = $row.$colname -replace "Old ID", "New ID"
$row
}
} # | Export-Csv "output.csv"
Note the use of pipeline variables to sidestep any $_
confusion inside the inner loop.
Upvotes: 4