I have a series of folders, named as follow
[[1254170]][folder1]
[[1212340]][folder2]
[[3245417]][folder3]
I want to rename them all as
[1254170]folder1
[1212340]folder2
[3245417]folder3
or at least
[1254170][folder1]
[1212340][folder2]
[3245417][folder3]
I edited the batch command I learned from a question I asked a year ago.
Get-ChildItem -path . -directory -recurse | Where {$_.Name -match '^\[\[\d\]\]'} | Rename-Item -NewName {$_.Name -replace '^\[\[\d\]\]','^\[\d\]'}
The command went through but nothing happened.
I also tried an edited version of the command from this answer
Get-ChildItem * -Filter "*`[`[*`]`]*" | Rename-Item -NewName { $_.name -replace '\[\[','\[' -replace '\]\]','\]' }
and I got this error
Rename-Item : Cannot rename the specified target, because it represents a path or device name.
At line:1 char:41
... `[*`]`]*" | Rename-Item -NewName { $_.name -replace '\[\[','\[' -repl ...
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
CategoryInfo : InvalidArgument: (:) [Rename-Item], PSArgumentException
FullyQualifiedErrorId : Argument,Microsoft.PowerShell.Commands.RenameItemCommand
Someone help me please? I am using Windows 11. Thank you.
CodePudding user response:
Use
Where-Object
with a-match
operation to find the folder (directory) names of interest, capturing the substrings of interest via regex capture groups ((...)
).You can pipe the matching folders to
Rename-Item
and use a delay-bind script block to dynamically determine the new name, in which you can refer to the captured substrings via the automatic$Matches
variable.- Inside the delay-bind script block, you can use
-f
, the string-formatting operator, to synthesize the new name.
- Inside the delay-bind script block, you can use
Get-ChildItem -Directory -Recurse |
Where-Object Name -match '^\[\[(. ?)\]\]\[(. ?)\]$' |
Rename-Item -NewName { '[{0}]{1}' -f $Matches[1], $matches[2] } -WhatIf
Note: The -WhatIf
common parameter in the command above previews the operation. Remove -WhatIf
once you're sure the operation will do what you want.
CodePudding user response:
$path = "D:\test"
Get-ChildItem $path -Filter "`[`[*`]`]`[*`]" -Directory|ForEach{
Rename-Item -Literal $_.FullName $_.Name.Replace("[[","[").Replace("]]","]")
}
CodePudding user response:
$testinput = '[[1254170]][folder1]'
$testinput
## catch the string and replace using regex
### replacing the matched string with capture group 2
$testinput -replace '(\[)(.*?)(\])', '${2}'
$testinput
C:\> [1254170]folder1
Regex Explanation
( open capture group 1
\ escaping the next character
[ matches [ literally
) closing capture group 1
( starting capture group 2
. matching any character except line breaks
* matches 0 or more of the preceding .
? making this lazy to capture as few as possible
) closing capture group 2
( starting capture group 3
\ escaping the next character
] matches ] literally
) closing capture group 3
(\[)(.*?)(\])
( [ )( [1254170] )( ] ) ( [ )( folder1 )( ] )
( 1 )( 2 )( 3 ) ( 1 )( 2 )( 3 )
CodePudding user response:
The latter [123123][folder1] i got with something like this:
$str = '[[1254170]][folder1]'
$newstr = ($str | select-string '\[[\w-] \]?').Matches.Value ($str | select-string '\[[\w-] \] $').Matches.Value
$newstr
[1254170][folder1]