Powershell 重命名包含方括号的动态文件名,来自目录中的文件类型扫描

Powershell Rename dynamic filenames containing square brackets, from the filetype scans in the directory

我不太了解(在细节和细节上)Powershell 在处理路径字符串中的方括号(只是因为它在内部多次转义字符串)时的愚蠢和荒谬 issues/bugs,我必须使用带星号 (*) 的正则表达式 match/catch 模式。

我进行了大量的谷歌搜索,发现有方法 [WildcardPattern]::Escape($Filename) 可以帮助我 Rename-Item 这样的动态文件路径,我认为下面的代码可以使用这样的动态路径,这些路径是文件的结果-在当前文件夹中键入扫描,但令人失望的是,它没有:

Set-Location "$PSScriptRoot"
$MkvFiles = Get-ChildItem -Filter *.mkv -Path $Path
Foreach ($MkvFile in $MkvFiles) {
    $MkvOrigName = [WildcardPattern]::Escape($MkvFile.Name)
    $MkvOrigFullname = [WildcardPattern]::Escape($MkvFile.FullName)
    If ($MkvOrigName -Match '.*(S[0-9]{2}E[0-9]{2}).*') {
        $NewNameNoExt = $MkvOrigFullname -Replace '.*(S[0-9]{2}E[0-9]{2}).*', ''
        $NewName = "$NewNameNoExt.mkv"
        Rename-Item $MkvOrigFullname -NewName $NewName
    }
}

当我 运行 在包含问题末尾给出的文件的文件夹上执行上述脚本时,Rename-Item 命令出现以下错误:

Rename-Item : An object at the specified path C:\Users\Username\Downloads\WebseriesName Season 
4\WebSeriesName.2016.S04E13.iNTERNAL.480p.x264-mSD`[eztv`].mkv does not exist.
At C:\Users\Username\Downloads\WebseriesName Season 4\BulkFileRenamerFinalv1.ps1:12 char:9
+         Rename-Item $MkvOrigFullname -NewName $NewName
+         ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

我正在处理的当前文件夹中的Webseries文件路径如下:

WebSeriesName.2016.S04E01.HDTV.x264-SVA[eztv].mkv
WebSeriesName.2016.S04E02.HDTV.x264-SVA[eztv].mkv
....
....
WebSeriesName.2016.S04E12.iNTERNAL.480p.x264-mSD[eztv].mkv
WebSeriesName.2016.S04E13.iNTERNAL.480p.x264-mSD[eztv].mkv

有人可以帮我解决这个问题,而不需要用文件名字符串包含的内容来解决问题,只要它们包含 S04E01S04E02 等字符串并且肯定包含 square括号?也就是说,如何转义方括号并将它们重命名为下面给出的名称,如上述代码所示?

S04E01.mkv
S04E02.mkv
....
....
S04E12.mkv
S04E13.mkv

如果使用管道,则无需担心转义路径。这是因为 PSPath 属性 会自动绑定到 Rename-Item 上的 -LiteralPath 参数。

Set-Location "$PSScriptRoot"
$MkvFiles = Get-ChildItem -Filter *.mkv -Path $Path
Foreach ($MkvFile in $MkvFiles) {
    If ($MkvFile.Name -Match '.*(S[0-9]{2}E[0-9]{2}).*') {
        $MkvFile | Rename-Item -NewName {"{0}{1}" -f $matches.1,$_.Extension}
    }
}

解释:

-NewName参数支持delay-bind scripting。所以我们可以使用脚本块来进行 property/string 操作。

如果路径查询不需要通配符,那么使用-LiteralPath是最好的方法。 -LiteralPath 值完全按照输入的方式绑定(literal/verbatim 字符串)。 -Path for Get-ChildItem 接受通配符,但 -Path for Rename-Item 不支持通配符。然而,在解析命令时,PowerShell 似乎仍然关心。如果您必须在接受通配符的 -Path 参数中转义某些通配符,则双引号路径需要 4 个反引号,单引号路径需要 2 个反引号。这是因为需要两级转义。

当对单个字符串使用 -match 时,即使在条件语句中,$matches 自动变量也会在匹配成功时更新。使用语法 $matches.capturegroupname$matches[capturegroupname] 访问捕获组匹配。由于您没有命名捕获组,系统自动将其命名为1。捕获组周围的第二组 () 应该是 2。重要的是要记住,当 -matchFalse 时,$matches 不会从其先前的值更新。


支持通配符的-Path参数中处理通配符的例子:

# Using double quotes in the path
$Path = "WebSeriesName.2016.S04E01.HDTV.x264-SVA````[eztv].mkv"
Get-ChildItem -Path $Path

# Using single quotes in the path
$Path = "WebSeriesName.2016.S04E01.HDTV.x264-SVA``[eztv].mkv"
Get-ChildItem -Path $Path

# Using LiteralPath
$Path = "WebSeriesName.2016.S04E01.HDTV.x264-SVA[eztv].mkv"
Get-ChildItem -LiteralPath $Path
Rename-Item -LiteralPath $Path -NewName 'MyNewName.mkv'

# Using WildcardPattern Escape method
$Path = 'WebSeriesName.2016.S04E01.HDTV.x264-SVA[eztv].mkv'
$EscapedPath = ([WildcardPattern]::Escape([WildcardPattern]::escape($path)))
Get-ChildItem -Path $EscapedPath