Method of changing suffix when PowerShell file name contains []

Posted by jesse_james on Fri, 16 Aug 2019 17:14:33 +0200

demand

As we all know, the way video websites publish videos has changed a lot. For example, the MP4 file is renamed mp41, similar to the following

PS E:\BaiduNetdiskDownload> ls *.mp41 -Recurse

//Directory?: E:\ Baidu Netdisk Download

Mode                LastWriteTime         Length Name                                                                    
----                -------------         ------ ----                                                                    
-a----        2019/8/11     20:42     1322066936 [SUBPIG][Eien no Nispa SP].mp41

However, according to the actual situation.

[SUBPIG][Eien no Nispa SP].mp41

The filename, which was rename d, was prompted to fail.

PS E:\BaiduNetdiskDownload> Rename-Computer "[SUBPIG][Eien no Nispa SP].mp41" "[SUBPIG][Eien no Nispa SP].mp4"
Rename-Computer : Unable to find acceptance of actual parameters“[SUBPIG][Eien no Nispa SP].mp4"Positional form parameters.
//Location line: 1 character: 1
+ Rename-Computer "[SUBPIG][Eien no Nispa SP].mp41" "[SUBPIG][Eien no N ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidArgument: (:) [Rename-Computer],ParameterBindingException
    + FullyQualifiedErrorId : PositionalParameterNotFound,Microsoft.PowerShell.Commands.RenameComputerCommand

autocomplete

Why is that? The reason is simple, because PowerShell has a special definition of [] symbols, so it can't be written that way.
Let's try to run it directly from the command line, and the system will automatically fill in what character escapes.

PS E:\BaiduNetdiskDownload> & '.\[SUBPIG][Eien no Nispa SP].mp41'

You can see that the string is preceded by a space, and the string is wrapped by'(single quotation mark)'. This method can be used to run command-line tools or executable programs that contain special characters, but it is not used when passing parameters.

Let's try to specify a path or file name in a parameter to see what the system will look like when it automatically completes.

PS E:\BaiduNetdiskDownload> Rename-Item -Path '.\`[SUBPIG`]`[Eien no Nispa SP`].mp41'

Maybe that's the right way to write a function.

function EscapeWord ($param1) {
    if ($param1 -match "[[]" -or $param1 -match "[]]") {
        $param1.replace('[', '`[').replace(']', '`]')
    }
}
EscapeWord "E:\BaiduNetdiskDownload\[SUBPIG][FAKE AFFAIR EP05].mp41"
E:\BaiduNetdiskDownload\`[SUBPIG`]`[FAKE AFFAIR EP05`].mp41

Start with a single data execution

PS E:\BaiduNetdiskDownload> Rename-Item -Path '.\`[SUBPIG`]`[Eien no Nispa SP`].mp41' -NewName '.\`[SUBPIG`]`[Eien no Nispa SP`].mp4' 
Rename-Item : Specified path E:\BaiduNetdiskDownload\`[SUBPIG`]`[Eien no Nispa SP`].mp41 The object below does not exist.

In fact, it failed.

Flexible solution

It's quite speechless. Since [] is redefined under PowerShell, CMD is always good. Mix it with CMD. This time, the name string is cut, the last string is cut off, and the name is replaced. The requirements can still be met, and the modification records will be saved in an additional file.

(Get-ChildItem *.mp41 -Recurse) | ForEach-Object { $fullname = $_.fullname 
    $fullname
    $NewName = $_.name
    $NewName = ($NewName[0..($NewName.Length - 2)] -join "")
    $NewName
    $info = "rename `"$fullname`" `"$NewName`""
    cmd /c $info
    $info | Out-File c:\333.txt -Append -Force -Encoding utf8
}

Highlight test

Final solution

The problem is solved, but the implementation method is too screwed. If there is a native method, the above operation will not be considered.
I search keywords

rename file PowerShell match []

Find the following ultimate solution at home.
https://answers.microsoft.com/en-us/windows/forum/windows_10-files/how-to-rename-image-files-in-a-folder-all-to-jpg/2a7e2873-e04b-472b-b239-afad2f2020fc

Sure enough, when it can't be solved, it's a sharp weapon to go directly to. net.

Get-ChildItem *.mp41 -Recurse | Rename-Item -newname { [io.path]::ChangeExtension($_.name, "mp4") }

stay https://stackoverflow.com/questions/5574648/use-regex-powershell-to-rename-files I also found a very interesting alternative, but the same, limited by [], is not suitable for my scenario.

Get-ChildItem *.mp41 | ForEach-Object{ Rename-Item $_ $(($_.name -replace '^filename_+','') -replace '_+',' ') }

The remaining questions

In fact, there is a pit here. If one day, it is necessary to replace the name of the file containing [], what should we do?

Topics: Windows encoding