简体   繁体   English

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

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

I don't much know(in details and specifics) about Powershell's silly and ridiculous issues/bugs in handling square brackets(just because it escapes strings multiple times internally) in the path strings, where I have to use Regex with asterisk(*) to match/catch the patterns.我不太了解(在细节和细节上)Powershell 在处理路径字符串中的方括号(只是因为它在内部多次转义字符串)中的愚蠢和荒谬的问题/错误,我必须在其中使用带有星号的正则表达式(*)匹配/捕捉模式。

I did heavy Googling and found that there's method [WildcardPattern]::Escape($Filename) that could help me Rename-Item such dynamic file paths, I thought the below code would work with such dynamic paths which are result of file-type scans in the current folder, but disappointingly, it doesn't:我进行了繁重的谷歌搜索,发现有方法[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}).*', '$1'
        $NewName = "$NewNameNoExt.mkv"
        Rename-Item $MkvOrigFullname -NewName $NewName
    }
}

I am getting the following error with Rename-Item command when I run the above script on the folder that contains the files such as given at the end of question:当我在包含问题末尾给出的文件的文件夹上运行上述脚本时,使用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
+         ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

The Webseries file paths in the current folder, that I am dealing with are like these:我正在处理的当前文件夹中的 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

Someone could help me figuring out this problem generically without need to headbang with what the filenames strings contain, as long as they contain the string like S04E01 , S04E02 etc. and surely contain square brackets?有人可以帮助我一般地解决这个问题,而无需使用文件名字符串包含的内容,只要它们包含S04E01S04E02等字符串并且肯定包含方括号? That is, how can I escape the square brackets and rename them, as apparent in the code afore-mentioned, to the names given below?也就是说,我怎样才能逃避方括号并将它们重命名,如前面提到的代码所示,为下面给出的名称?

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

If you use the pipeline, you don't need to worry about escaping paths.如果使用管道,则无需担心 escaping 路径。 This is because PSPath property will automatically bind to the -LiteralPath parameter on Rename-Item .这是因为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}
    }
}

Explanation:解释:

The -NewName parameter supports delay-bind scripting . -NewName参数支持延迟绑定脚本 So we can use a script block to do the property/string manipulation.所以我们可以使用脚本块来进行属性/字符串操作。

If wildcards are not needed for the path query, then using -LiteralPath is the best approach.如果路径查询不需要通配符,那么使用-LiteralPath是最好的方法。 The -LiteralPath value is bound exactly as typed (literal/verbatim string). -LiteralPath值完全按照键入的方式绑定(文字/逐字字符串)。 -Path for Get-ChildItem accepts wildcards, but -Path for Rename-Item does not support wildcards. Get-ChildItem -Path接受通配符,但Rename-Item -Path不支持通配符。 Yet it seems like PowerShell still cares when parsing the command.然而,在解析命令时,PowerShell 似乎仍然很关心。 If you must escape some wildcard characters in a -Path parameter that accepts wildcards, then double quoted paths require 4 backticks and single quoted paths require 2 backticks.如果您必须在接受通配符的-Path参数中转义某些通配符,则双引号路径需要 4 个反引号,而单引号路径需要 2 个反引号。 This is because two levels of escape are required.这是因为需要两个级别的转义。

When using -match against a single string even if in a conditional statement, the $matches automatic variable is updated when a match is successful.即使在条件语句中对单个字符串使用-match时,匹配成功时也会更新$matches自动变量。 Capture group matches are accessed using syntax $matches.capturegroupname or $matches[capturegroupname] .使用语法$matches.capturegroupname matches.capturegroupname 或$matches[capturegroupname]访问捕获组匹配。 Since you did not name the capture group, it was automatically named 1 by the system.由于您没有命名捕获组,因此系统自动将其命名为1 A second set of () around a capturing group, would have been 2 .围绕捕获组的第二组()将是2 It is important to remember that when -match is False , $matches is not updated from its previous value.重要的是要记住,当-matchFalse时, $matches不会从其先前的值更新。


Examples of handling wildcard characters in -Path parameters that support wildcards:处理支持通配符的-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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM