Reputation: 303
I need to add a patch to a filename when exporting which is generated from the Get-Childitem
.
Get-ChildItem 'C:\temp\*.txt' | foreach-Object {
*some magic here*
} | export-csv -NoTypeInformation -Force -Encoding UTF8 ($_.basename + ".txt")
Works fine, but now I want to add a path to the resulting txt files.
I changed the code to
| export-csv -NoTypeInformation -Force -Encoding UTF8 -path "c:\temp\csv_temp\"($_.basename + ".csv")
which failed. I also tried:
| export-csv -NoTypeInformation -Force -Encoding UTF8 ("c:\temp\test\"+ $_.basename + ".txt")
also with the same result.
Upvotes: 1
Views: 2061
Reputation: 439277
The ($_.basename + ".txt")
in your Export-Csv
call cannot work, because $_
is not defined when used directly as a parameter value, outside of a script block.
(Unless you had explicitly assigned an object with a .basename
property to $_
beforehand - which you shouldn't do - $_
is undefined, so ($_.basename + ".txt")
evaluates to ".txt"
, and you're effectively outputting to a file named .txt
.)
You generally cannot use $_
- or even a variable passed from an earlier pipeline stage with the -PipelineVariable
/ -pv
common parameter - as a direct parameter value, outside of a script block.[1]
Therefore, I suggest you restructure your command as follows (making use of the PSv4+ -pv
/ -PipelineVariable
common parameter for convenience, but it's easy to adapt the solution to PSv3-):
Get-ChildItem 'C:\temp\*.txt' -pv fileObj | ForEach-Object {
*some magic here* |
Export-Csv -NoTypeInformation -Force -Encoding UTF8 ($fileObj.basename + ".txt")
}
By moving the Export-Csv
call into the ForEach-Object
script block, you can make use of the $fileObj
variable created by -pv fileObj
, representing the input file at hand.
While the input file is also reflected in $_
inside the script block, $_
is redefined in the context of the embedded pipeline, so -pv fileObj
is a convenient way to create a variable that refers to the outer pipeline's input object as $fileObj
; alternatively, you could execute $fileObj = $_
at the start of the script block, which makes the solution work in PSv3- too.
The alternative target-file-path arguments are then:
# Using an expandable string with an *embedded* expression:
# Note the $(...) surrounding the expression
"c:\temp\csv_temp\$($fileObj.basename + ".csv")"
# Using an expression (string concatenation):
("c:\temp\test\" + $fileObj.basename + ".txt")
[1] The reason is that directly passed values are bound to their parameter variables before any objects are sent through the pipeline.
Upvotes: 2