Reputation: 389
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
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