Home > Blockchain >  PowerShell perform a command adding an extension to list of files
PowerShell perform a command adding an extension to list of files

Time:10-25

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.

  • Related