Fai
Fai

Reputation: 389

Pipeline input to out-file

I was trying to process a list of files and write them out to new places. For each file I'm making a new PS object with a file name and the new content. Then I want to write a file with the saved filename and the modified content. This does not work:

$ci | % { new-object -typename psobject -property @{out=(get-content  $_ | % { if ($_ -match '^[0-9].* [AB]: (.*)$') { $matches[1] } } |% { $_ -replace '(\.|\?|,|!)',''  } );
name=$_.Name} | 
Out-File -PSPath ("e:\training\deu\$($_.Name)") -InputObject $_.out }
The property 'out' cannot be found on this object. Verify that the property exists.
At line:1 char:418
+ ... training\deu\$($_.Name)") -InputObject $_.out }
+                    ~~~~~~~
+ CategoryInfo          : NotSpecified: (:) [], PropertyNotFoundException
+ FullyQualifiedErrorId : PropertyNotFoundStrict

However the following does work:

$all = $ci | % { new-object -typename psobject -property @{out=(get-content  $_ | % { if ($_ -match '^[0-9].* [AB]: (.*)$') { $matches[1] } } |% { $_ -replace '(\.|\?|,|!)','' } );
name=$_.Name}  }
$all | % {out-file -PSPath ("e:\training\deu\$($_.Name)") -InputObject $_.out}

what's the difference between the two? Clearly the property out does exist.

Upvotes: 1

Views: 664

Answers (1)

Ryan Bemrose
Ryan Bemrose

Reputation: 9266

Out-File doesn't expand piped lists into the $_ variable. Only certain cmdlets do that, like Foreach-Object and Where-Object (and more generally, any cmdlet that follows the Begin, Process, End workflow)

In the second case, your use of $_.out is inside a scriptblock which is passed to a Foreach-Object. Foreach performs some magic, in which it iterates over the piped array, sets $_ to the array element, and calls your scriptblock.

Out-File does not do any of that. In your first code, the value of $_ is an element of $ci, and was set by the outermost foreach. That object doesn't contain an out member, hence the error.

Upvotes: 1

Related Questions