tags:

views:

270

answers:

2

I'm trying to write a script in powershell to batch convert video files.

The way I intend to use it is to go to some folder full of video files and run it. It uses a conversion program that can be run in "command-line mode" (named handbrake) and saves the converted files with "-android" appended to them before the file extension. For example, if I have a file named video1.avi in the folder, after running the script the folder has 2 files: video1.avi and video1-android.avi

The reason I want to do this this way is so that I can check if, for each video file, there is a converted version of it (with -android appended to the name). And if so, skip the conversion for that file.

And this is where I'm having touble. The problem is the Test-Path's behavior (the cmdlet I'm using to test if a file exists).

What happens is, if the video file has an "unusual" name (for example in my case it's video[long].avi) Test-Path always returns False if you try to check if that file exists.

An easy way for you to test this is for example to do this:

Go to an empty folder, run notepad to create a file with "[" in its name:

&notepad test[x].txt

Save the file

then do this:

Get-ChildItem | ForEach-Object {Test-Path $_.FullName}

It does not return true! It should right? Well it doesn't if the file has "[" in its name (I didn't check for any other special characters)

I've realized that if you escape the "[" and "]" it works

Test-Path 'test`[x`].txt'

returns true.

How can I go around this issue? I want to be able to: given a BaseName of a file, append it "-android.avi" and check if a file with that name exists.

Thanks, Rui

A: 
 dir | % {test-path "$($_.Name)-android.avi"}
Doug Finke
Can you elaborate on that, why the $($_.Name) and the "%{ }"?
Rui
`%` and `Foreach` are aliases for the Forech-Object cmdlet. Inside a string, you can do simple variable expansion like so `"$_"` but if you want to evaluate an expression such as accessing a property of an object, you need to use a subexpression e.g. `"$($_.Name)"`.
Keith Hill
+3  A: 

Many PowerShell cmdlets have Path parameters that support wildcarding. As you have observed, in PowerShell not only is * a wildcard but [ and ] are also considered wildcard characters. You can read more about this in the help topic about_Wildcards.

For your issue, if you don't need wildcarding then I would recommend using the -LiteralPath parameter. This parameter doesn't support wildcarding and accepts [ and ] as literal path characters e.g.:

Get-ChildItem | ForEach {Test-Path -LiteralPath `
                         "$([io.path]::ChangeExtension($_.FullName,'avi'))"}

FYI, the reason piping the output of Get-ChildItem directly into Test-Path works is because the LiteralPath parameter has an alias "PSPath" that maps to the PSPath property on the FileInfo object output by Get-ChildItem. That property gets bound to the LiteralPath (er PSPath) parameter "by property name".

Keith Hill
Thanks, that was exactly what I needed
Rui