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
有人可以帮我解决这个问题,而不需要用文件名字符串包含的内容来解决问题,只要它们包含 S04E01
、S04E02
等字符串并且肯定包含 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
。重要的是要记住,当 -match
为 False
时,$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
我不太了解(在细节和细节上)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
有人可以帮我解决这个问题,而不需要用文件名字符串包含的内容来解决问题,只要它们包含 S04E01
、S04E02
等字符串并且肯定包含 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
。重要的是要记住,当 -match
为 False
时,$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