Reputation: 9277
I created the following command for merge all csv files that matches with a filter inside a folder and outputs it into an outfile.
$mainPath="C:\\users\\myuser\\temp";
$mergeFilter="myfile.csv";
$outFile = "C:\\users\\myuser\temp\test.csv";
Get-ChildItem $mainPath -Recurse -Include $mergeFilter |
Select-Object -ExpandProperty FullName |
Import-Csv -Delimiter ';' |
Select-Object *,@{Name='Date'; Expression={"$dummyvariable"}}; |
Export-Csv $outFile -NoTypeInformation -Delimiter ';'
My issue is that, I want to add an extra column when some CSV's are merged using a variable called $dummyvariable but I dont know where I have to initialize it in order to get the value in the Expression={"..."}. If I declare before in the pipeline it doesn't work (I need to do it higher on the pipe to get a directory name)
Do you know how I can declare this variable and recover on the pipe that starts with "Select-Object"?
Thanks in advance
Best Regards.
Jose
Upvotes: 6
Views: 7250
Reputation: 438093
I think you're looking for the commmon -PipelineVariable
(-pv
) parameter (PSv4+), which stores a given cmdlet's current output object in a variable that can be referenced in script blocks in later pipeline segments.
Here's a simplified example:
# Create sample input file.
@'
foo;bar
1;2
'@ > file.csv
# NOTE: -pv fileObj (same as: -PipelineVariable fileObj)
# stores (potentially each) `Get-Item` output object in var. $fileObj,
# accessible in script blocks later in the the pipeline.
Get-Item file.csv -pv fileObj |
Select-Object -ExpandProperty FullName |
Import-Csv -Delimiter ';' |
Select-Object *, @{ n='Date'; e={ $fileObj.LastWriteTime } }
The above yields something like:
foo bar Date
--- --- ----
1 2 2/17/18 4:17:25 PM
That is, -pv fileObj
made Get-Item
store its current output object in variable $fileObj
, which the last pipeline segment was able to reference in the property-definition script block.
Note:
$
in the -pv
/ -PipelineVariable
argument: the mere variable name must be passed (e.g. fileObj
); only on accessing the resulting variable is $
required (e.g. $fileObj
).Upvotes: 9
Reputation: 10019
You should be able to use a ForEach-Object
to specify $dummyvariable
without affecting other elements of the pipeline.
$mainPath="C:\\users\\myuser\\temp";
$mergeFilter="myfile.csv";
$outFile = "C:\\users\\myuser\temp\test.csv";
Get-ChildItem $mainPath -Recurse -Include $mergeFilter |
Select-Object -ExpandProperty FullName |
Import-Csv -Delimiter ';' |
ForEachObject {$dummyvariable = "..."} |
Select-Object *,@{Name='Date'; Expression={"$dummyvariable"}}; |
Export-Csv $outFile -NoTypeInformation -Delimiter ';'
This is untested. You may need to specify that the properties need to be passed along to the next pipeline by doing this:
ForEachObject {$dummyvariable = "...";$_} |
My approach would be to break things down though as advised by vonPryz. Makes it easier to debug and to maintain.
Upvotes: 0