需要使用 Powershell 向文件名批量添加字符
Need to batch add characters to filenames using Powershell
我有一系列文件都命名为:
PRT14_WD_14220000_1.jpg
我需要在最后一个下划线之后和数字之前添加两个零,这样它看起来像 PRT14_WD_14220000_001.jpg
我试过了
(dir) | rename-Item -new { $_.name -replace '*_*_*_','*_*_*_00' }
感谢任何帮助。
以下假设您 .BaseName
的最后一部分总是需要添加两个零。它的作用...
- 伪造你从
Get-Item/Get-ChildItem
得到的 fileinfo
对象
用适当的 cmdlet 替换它。 [咧嘴一笑]
- 使用
_
作为拆分目标将 .BaseName
拆分为多个部分
- 将两个零添加到上述拆分的最后部分
- 将零件合并成
$NewBaseName
- 获取
.FullName
并将原始 BaseName 替换为 $newBaseName
- 显示新文件名
您仍然需要重命名,但这非常直接。 [咧嘴一笑]
这是代码...
# fake getting a file info object
# in real life, use Get-Item or Get-ChildItem
$FileInfo = [System.IO.FileInfo]'PRT14_WD_14220000_1.jpg'
$BNParts = $FileInfo.BaseName.Split('_')
$BNParts[-1] = '00{0}' -f $BNParts[-1]
$NewBasename = $BNParts -join '_'
$NewFileName = $FileInfo.FullName.Replace($FileInfo.BaseName, $NewBaseName)
$NewFileName
输出=D:\Data\Scripts\PRT14_WD_14220000_001.jpg
最接近您尝试的是这个。在正则表达式中,通配符是 .*
。括号做分组,后面用美元符号数字引用。
dir *.jpg | rename-Item -new { $_.name -replace '(.*)_(.*)_(.*)_','___00' } -whatif
What if: Performing the operation "Rename File" on target "Item: C:\users\admin\foo\PRT14_WD_14220000_1.jpg Destination: C:\users\admin\foo\PRT14_WD_14220000_001.jpg".
好的,当你想要最多两个零填充的数字时,这是我的看法。 $num 必须是我想要的 .tostring() 方法的整数。
dir *.jpg | rename-item -newname { $a,$b,$c,$num = $_.basename -split '_'
$num = [int]$num
$a + '_' + $b + "_" + $c + '_' + $num.tostring('000') + '.jpg'
} -whatif
operates on regexes (regular expressions) , not wildcard expressons 例如 *
(单独),这就是您要使用的。
概念上更直接的方法是将替换集中在字符串的结尾:
Get-ChildItem | # `dir` is a built-in alias for Get-ChildItem`
Rename-Item -NewName { $_.Name -replace '(?<=_)[^_]+(?=\.)', '00$&' } -WhatIf
注意:上面命令中的-WhatIf
common parameter预览操作。一旦您确定该操作将执行您想要的操作,请删除 -WhatIf
。
(?<=_)[^_]+(?=\.)
匹配非 _
字符的非空 运行 (+
)。 ([^_]
) 前面是 _
((?<=_
),后面是文字 .
((?=\.)
),不包括前面的 _
和跟随 .
来自比赛 捕获的 ((?<=...)
和 (?=...)
是非捕获 环顾四周 断言)。
- 简而言之:这匹配并捕获最后一个
_
之后和文件扩展名开始之前的字符。
00$&
替换与 00
匹配的内容,然后是匹配捕获的内容 ($&
).
在后续评论中,您提到不只是盲目地插入 00
,而是要 0
-在最后一个 [=20= 之后左填充数字] 到 3 位数字,无论数字是多少。
在PowerShell [Core] 6.1+中,可以这样实现:
Get-ChildItem |
Rename-Item -NewName {
$_.Name -replace '(?<=_)[^_]+(?=\.)', { $_.Value.PadLeft(3, '0') }
} -WhatIf
作为替换操作数的脚本块 ({ ... }
) 将每个匹配作为 Match
实例存储在自动变量 $_
中,其 .Value
属性 包含捕获的文本。
在捕获的文本上调用 .PadLeft(3, '0')
0
-将其左填充到 3 位数字并输出结果,这将替换手头的正则表达式匹配。
快速演示:
PS> 'PRT14_WD_14220000_1.jpg' -replace '(?<=_)[^_]+(?=\.)', { $_.Value.PadLeft(3, '0') }
PRT14_WD_14220000_001.jpg # Note how '_1.jpg' was replaced with '_001.jpg'
在 早期的 PowerShell 版本 中,您必须直接使用 .NET [regex]
类型的 .Replace()
method,其工作原理基本相同:
Get-ChildItem |
Rename-Item -NewName {
[regex]::Replace($_.Name, '(?<=_)[^_]+(?=\.)', { param($m) $m.Value.PadLeft(3, '0') })
} -WhatIf
我有一系列文件都命名为:
PRT14_WD_14220000_1.jpg
我需要在最后一个下划线之后和数字之前添加两个零,这样它看起来像 PRT14_WD_14220000_001.jpg
我试过了
(dir) | rename-Item -new { $_.name -replace '*_*_*_','*_*_*_00' }
感谢任何帮助。
以下假设您 .BaseName
的最后一部分总是需要添加两个零。它的作用...
- 伪造你从
Get-Item/Get-ChildItem
得到的fileinfo
对象 用适当的 cmdlet 替换它。 [咧嘴一笑] - 使用
_
作为拆分目标将.BaseName
拆分为多个部分 - 将两个零添加到上述拆分的最后部分
- 将零件合并成
$NewBaseName
- 获取
.FullName
并将原始 BaseName 替换为$newBaseName
- 显示新文件名
您仍然需要重命名,但这非常直接。 [咧嘴一笑]
这是代码...
# fake getting a file info object
# in real life, use Get-Item or Get-ChildItem
$FileInfo = [System.IO.FileInfo]'PRT14_WD_14220000_1.jpg'
$BNParts = $FileInfo.BaseName.Split('_')
$BNParts[-1] = '00{0}' -f $BNParts[-1]
$NewBasename = $BNParts -join '_'
$NewFileName = $FileInfo.FullName.Replace($FileInfo.BaseName, $NewBaseName)
$NewFileName
输出=D:\Data\Scripts\PRT14_WD_14220000_001.jpg
最接近您尝试的是这个。在正则表达式中,通配符是 .*
。括号做分组,后面用美元符号数字引用。
dir *.jpg | rename-Item -new { $_.name -replace '(.*)_(.*)_(.*)_','___00' } -whatif
What if: Performing the operation "Rename File" on target "Item: C:\users\admin\foo\PRT14_WD_14220000_1.jpg Destination: C:\users\admin\foo\PRT14_WD_14220000_001.jpg".
好的,当你想要最多两个零填充的数字时,这是我的看法。 $num 必须是我想要的 .tostring() 方法的整数。
dir *.jpg | rename-item -newname { $a,$b,$c,$num = $_.basename -split '_'
$num = [int]$num
$a + '_' + $b + "_" + $c + '_' + $num.tostring('000') + '.jpg'
} -whatif
*
(单独),这就是您要使用的。
概念上更直接的方法是将替换集中在字符串的结尾:
Get-ChildItem | # `dir` is a built-in alias for Get-ChildItem`
Rename-Item -NewName { $_.Name -replace '(?<=_)[^_]+(?=\.)', '00$&' } -WhatIf
注意:上面命令中的-WhatIf
common parameter预览操作。一旦您确定该操作将执行您想要的操作,请删除 -WhatIf
。
(?<=_)[^_]+(?=\.)
匹配非_
字符的非空 运行 (+
)。 ([^_]
) 前面是_
((?<=_
),后面是文字.
((?=\.)
),不包括前面的_
和跟随.
来自比赛 捕获的 ((?<=...)
和(?=...)
是非捕获 环顾四周 断言)。- 简而言之:这匹配并捕获最后一个
_
之后和文件扩展名开始之前的字符。
- 简而言之:这匹配并捕获最后一个
00$&
替换与00
匹配的内容,然后是匹配捕获的内容 ($&
).
在后续评论中,您提到不只是盲目地插入 00
,而是要 0
-在最后一个 [=20= 之后左填充数字] 到 3 位数字,无论数字是多少。
在PowerShell [Core] 6.1+中,可以这样实现:
Get-ChildItem |
Rename-Item -NewName {
$_.Name -replace '(?<=_)[^_]+(?=\.)', { $_.Value.PadLeft(3, '0') }
} -WhatIf
作为替换操作数的脚本块 (
{ ... }
) 将每个匹配作为Match
实例存储在自动变量$_
中,其.Value
属性 包含捕获的文本。在捕获的文本上调用
.PadLeft(3, '0')
0
-将其左填充到 3 位数字并输出结果,这将替换手头的正则表达式匹配。
快速演示:
PS> 'PRT14_WD_14220000_1.jpg' -replace '(?<=_)[^_]+(?=\.)', { $_.Value.PadLeft(3, '0') }
PRT14_WD_14220000_001.jpg # Note how '_1.jpg' was replaced with '_001.jpg'
在 早期的 PowerShell 版本 中,您必须直接使用 .NET [regex]
类型的 .Replace()
method,其工作原理基本相同:
Get-ChildItem |
Rename-Item -NewName {
[regex]::Replace($_.Name, '(?<=_)[^_]+(?=\.)', { param($m) $m.Value.PadLeft(3, '0') })
} -WhatIf