替换数组中自定义 PSObject 的属性中的字符串

Replace strings in properties of custom PSObjects in an array

我将 CSV 文件读入对象数组(使用 Import-Csv)。如果我使用 Export-Csv 将该数据写回磁盘,我得到的正是我所期望的,格式正确的 CSV。

现在我需要更改该 CSV 中的一些数据。其中之一是需要更换的字符串。但是如果我做一个简单的:

$thisIsTheArrayOfObjects -replace "Old ID", "New ID" 

它会生成一个字符串数组。 (替换发生了,但是我数组中的所有对象都以某种方式转换为字符串)

当然现在 Export-Csv 没有提供预期的结果。它只是导出一个文件,其中包含我数组中字符串的所有长度。

如何替换数组中 PSOBJECTS 属性中的字符串?

How can i replace strings in properties of PSOBJECTS in an array?

你对每个对象都这样做。

$thisIsTheArrayOfObjects | ForEach-Object {
    $_.foo = $_.foo -replace "Old ID" , "New ID" # replace string in a property
    $_                                           # output the object back onto the pipeline
}

请记住 -replace 有两个问题:

  • 它适用于正则表达式。从技术上讲,如果您想进行 文字 替换,您必须对第一个参数 ([regex]::escape("Old ID")) 进行正则表达式转义,除非 "Old ID" 不包含任何特殊字符正则表达式。如果它来自用户输入,最好将其转义。
  • 不区分大小写。

要进行区分大小写的文字替换,请使用 .NET-native String.Replace(),它也可用:

$thisIsTheArrayOfObjects | ForEach-Object {
    $_.foo = $_.foo.Replace("Old ID", "New ID") # replace string in a property
    $_                                          # output the object back onto the pipeline
}

要对 CSV 数据中的每一列应用操作,您必须创建一个嵌套循环。 Get-Member cmdlet 可以提供帮助。原理同上

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"

注意使用管道变量来回避内部循环中的任何$_混淆。