Friend2000
Friend2000

Reputation: 55

How can I replace a string inside a pipe?

I'm trying to replace some specific parts of a selected string but am only returning the length property. Here's my code:

Get-ChildItem "StartPath/Something/Files" -Recurse -File | Select "FullName | Foreach {$_.FullName -replace "StartPath",""} | Export-Csv "ResultPath.csv"

If I omit the foreach bit, this works in that it spits out the full path. I'd like to trim the full path as I'm iterating over tons of files. I'm trying to replace a bit of the path in the beginning of the string but my code above just spits out a CSV file with just string lengths.

Looks like:

"123"
"12"
"52"

and so forth.

The intended result would be a csv file with instead of:

StartPath/Something/Files1
StartPath/Something/Files2

I'd have

Something/Files1
Something/Files2

I've tried a number of things and can't seem to figure it out. Any help is appreciated.

Upvotes: 3

Views: 396

Answers (1)

mklement0
mklement0

Reputation: 438378

If you pass a string to select / Select-Object (to its positionally implied -Property parameter), it must be a property name.[1]

If you want to perform open-ended operations and/or produce open-ended output for each input object, you must use the ForEach-Object cmdlet:

Get-ChildItem "StartPath/Something/Files" -Recurse -File | 
  ForEach-Object { 
    [pscustomobject] @{ FullName = $_.FullName -replace 'StartPath' } 
  } | 
    Export-Csv "ResultPath.csv"

Note the use of a [pscustomobject] wrapper that defines a FullName property, so that Export-Csv creates a CSV with that property as its (only) column.

If you pipe [string] instances directly to Export-Csv, their properties are serialized to the output file - and a [string]'s only (public) property is its length (.Length), which is what you saw.


[1] There's also a way to create properties dynamically, using so-called calculated properties, which are defined via hash tables.

Upvotes: 3

Related Questions