EKortz
EKortz

Reputation: 25

Replace strings in properties of custom PSObjects in an array

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

Answers (1)

Tomalak
Tomalak

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:

  • It works with regex. Technically you must regex-escape the first parameter ([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.
  • It's case-insensitive.

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

Related Questions