我正在尝试在powershell中编写一个脚本来批量转换视频文件。
我打算使用它的方法是去一些充满视频文件的文件夹并运行它。它使用可以在“命令行模式”(名为handbrake)中运行的转换程序,并在文件扩展名之前保存转换后的文件,并附加“-android”。例如,如果我在文件夹中有一个名为video1.avi的文件,则在运行脚本后该文件夹有2个文件:video1.avi和video1-android.avi
我想这样做的原因是我可以检查每个视频文件是否有转换后的版本(名称附加了-android)。如果是这样,请跳过该文件的转换。
这就是我有点烦恼的地方。问题是Test-Path的行为(我用来测试文件是否存在的cmdlet)。
如果视频文件具有“异常”名称(例如在我的情况下是视频[long] .avi),则会发生什么?如果您尝试检查该文件是否存在,则Test-Path始终返回False。
您可以通过以下方式轻松测试:
转到空文件夹, 运行记事本以创建名称中带有“[”的文件:
¬epad test[x].txt
保存文件
然后这样做:
Get-ChildItem | ForEach-Object {Test-Path $_.FullName}
它不会返回true!应该对吗?好吧,如果文件名称中有“[”(我没有检查任何其他特殊字符)
,则不会我已经意识到,如果你逃避“[”和“]”它就会起作用
Test-Path 'test`[x`].txt'
返回true。
我该如何解决这个问题?我希望能够:给定文件的BaseName,将其附加到“-android.avi”并检查是否存在具有该名称的文件。
谢谢, 锐
答案 0 :(得分:8)
许多PowerShell cmdlet都具有支持通配符的Path参数。正如您所观察到的,在PowerShell中,*
不仅是通配符,而且[
和]
也被视为通配符。您可以在帮助主题about_Wildcards中阅读有关此内容的更多信息。
对于您的问题,如果您不需要通配符,那么我建议使用-LiteralPath参数。此参数不支持通配符,并接受[
和]
作为文字路径字符,例如:
Get-ChildItem | ForEach {Test-Path -LiteralPath `
"$([io.path]::ChangeExtension($_.FullName,'avi'))"}
仅供参考,将Get-ChildItem的输出直接传递到Test-Path的原因是因为LiteralPath参数具有别名“PSPath”,该别名映射到Get-ChildItem输出的FileInfo对象上的PSPath属性。该属性绑定到LiteralPath(er PSPath)参数“按属性名称”。
答案 1 :(得分:1)
dir | % {test-path "$($_.Name)-android.avi"}