PowerShell/Regex:重命名所有文件,修改序号

PowerShell/Regex: Rename all files, modify number sequence

我目前有一个包含数千个文件的目录。
每个文件在文件名中的某处都有 _c04__c05_ 等。

我需要将所有这些文件重命名为 _c004__c005_
唯一需要改变的是添加额外的零。
该字母将始终为 c.

我对正则表达式很陌生,不知道搜索和替换这串字符的正确方法。

到目前为止我已经编写了这段代码,但显然这是不可扩展的...
(因为它只修改 04 而不是 01-99)

dir | rename-item -NewName {$_.name -replace "_c04_","_c004_"}
Get-ChildItem | % {
    $NewName = $_.Name -replace '_c(\d{2})_','_c0_'
    Rename-Item -Path $_.FullName -NewName $NewName
}

您可能正在寻找类似的东西,找到与 _c.._ 匹配的任何内容,其中 . 是任何数字 0-9,然后将其替换为前缀为 0 的那些数字。

向您展示如何在正则表达式中使用捕获组 ((...)) 并引用它在替换字符串 (</code>) 中捕获的内容来执行所需的操作名称转换。</p> <ul> <li><p>PowerShell 使用 .NET Framework 的 <a href="https://docs.microsoft.com/en-us/dotnet/standard/base-types/regular-expression-language-quick-reference" rel="nofollow noreferrer">regular-expression language</a>, a brief introduction to which is available when your run <a href="https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_Regular_Expressions" rel="nofollow noreferrer"><code>Get-Help about_Regular_Expressions.
正则表达式不仅用于 -replace,还用于 -match 运算符和 cmdlet,例如 Select-String.

  • 具体适用于 -replace 运算符的语法在 .

    中介绍
  • 您自己的解决方案尝试优于基于 % (ForEach-Object) 的方法(显示在 colsw 的回答中),因为它仅涉及 单个 调用 Rename-Item,它使用 来计算新名称。

    这是一个工作变体,它使用 zero-width lookbehind/ahead assertions 只匹配应该插入 0 位置 ,而无需重复任何部分输入字符串:

    Get-ChildItem | Rename-Item -NewName { $_.Name -replace '(?<=_c)(?=\d{2}_)', '0' } -WhatIf
    
    • 常用参数-WhatIf预览修改;删除它以执行实际重命名。

    • 正如 colsw 的回答一样, 引号 ('...') 用于正则表达式和替换字符串,因为 "..." 可能会与 PowerShell 的前期字符串扩展(插值)产生混淆;例如,"" 将被解释为 变量 引用。

      • 如果你使用 "..." 因为你想在前面的字符串中嵌入 PowerShell 变量值和表达式,请务必转义 $ 用于正则表达式引擎 as `$.

      • 另一种方法是坚持使用单引号并使用 -f 运算符嵌入一个值;例如'foo-{0}' -f $var

      • 无论哪种方式,一个陷阱是嵌入在变量值中的任何元字符都将具有语法意义,并且要将它们 逐字处理 需要调用 [regex]::Escape() 用于正则表达式操作数,并将任何嵌入的 $ 字符加倍用于替换操作数,因此最好的方法是使用类似:

        '...' -replace ('foo-{0}' -f [regex]::Escape($var1)),
                       ('bar-{0}' -f $var2.Replace('$', '$$'))
        
    • 请注意,任何名称不会导致转换的输入文件都将保持不变;但是,您可以通过使用 通配符模式 预选感兴趣的文件来缩小要处理的文件集:
      Get-ChildItem *_c[0-9][0-9]_* | Rename-Item ...