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 ...
我目前有一个包含数千个文件的目录。
每个文件在文件名中的某处都有 _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 ...