I have a Windows executable munge.exe
which takes an input .dat
file and produces a file with the -o
parameter for the output filename. I want to append (not replace) an .out
extension to the output, so I call it like this for foo.dat
and bar.dat
:
munge foo.dat -o foo.dat.out
munge bar.dat -o bar.dat.out
I just got a large directory of various files, among them many .dat
files. Many of them have spaces in their names. It's so much work to munge them manually. I thought PowerShell could help. As a newbie, I did a few searches and came up with this, making liberal use of aliases:
dir *.dat | %{munge $_.name -o $_.name ".out"}
Needless to say, it didn't work. I tried to find out where I went wrong, so I just tried to echo the commands to see what was going on. (The wonderful -whatif
as you might expect doesn't help me, because of course it doesn't work with script blocks. Of course. Wonderful)
dir *.dat | %{echo munge $_.name -o $_.name ".out"}
No go; it thinks that -o
is a parameter of echo
. So let's quote the thing!
dir *.dat | %{echo "munge $_.name -o $_.name .out"}
Oops I'm getting .name
and
in the interpolation. Maybe if I use the ${…}
format and leave out the
since it's interpolation.
dir *.dat | %{echo "munge ${_.name} -o ${_.name} .out"}
Um … no. That gives me munge -o .out
.
(sigh) Looks like I'll have to learn all the Powershell tricks just to do basic things (as I had to do with Bash). Nothing is simple I guess.
What is the way I'm supposed to do it?
CodePudding user response:
The relevant documentation in this case is about Operator Precendence.
You need to use the Grouping operator ( )
so that the string concatenation between $_.Name
and .out
is resolved first in the expression:
Get-ChildItem *.dat | ForEach-Object {
munge $_.name -o ($_.name ".out")
}
As for the second example, where you attempt to echo
the result, in this case, you need the Subexpression operator $( )
so that the string interpolation is resolved first :)
Get-ChildItem *.dat | ForEach-Object {
echo "munge $($_.name) -o $($_.name ".out")"
}
Lastly, regarding -WhatIf
, echo
(Write-Output
) is not a cmdlet that supports ShouldProcess
, hence no -WhatIf
switch is available for it.