需要使用 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