使用 Powershell 将第二次出现的“-”替换为“_”
Replacing 2nd occurrence of "-" with "_" using Powershell
我一直在使用 Powershell 来简化创建目录、重命名和移动文件等重复性任务。我正在处理视频和 PDF 文件,其中所需的文件名语法非常具体。到目前为止,我已经能够纠正我遇到的所有常见错误 运行,但是这个错误让我很困惑。
我的文件的正确语法包括:
01A-50_02A-50-CIPP-PRE.MP4
01AA-50_02AA-50-CIPP-PNSL.PDF
W01AA-48_02AA-48-CIPP-PST-CMP.MPG
我收到了大量如下所示的文件:
01A-50-02A-50-CIPP-PRE.MP4
01AA-50-02AA-50-CIPP-PNSL.PDF
W01AA-48-02AA-48-CIPP-PST-CMP.MPG
我需要用下划线替换第二个破折号,同时保持其他破折号不受影响。否则我可以在 excel 的帮助下批量执行此操作,但我希望有一个简短的代码可以找到并更正此语法错误,而无需将列表导出到 excel,使用文本到列,然后将字母数字部分连接在一起。我也不想手动更正所有这些文件名。
根据我的研究,不可能针对特定字符的出现进行替换。我最接近的想法是我找到了一个涉及 REGEX 以及识别和替换模式的解决方案。我没能对此做任何有建设性的事情。
我使用此代码的方式是打开包含命名错误文件的文件夹,在那里打开 Powershell window,从我桌面上的 txt 文件复制代码,然后将其粘贴到 Powershell .
如有任何帮助,我们将不胜感激。
查看您的示例,似乎第二个 -
总是出现在数字之间。类似于 $Variable -replace 'REGEX','_'
使用下面的正则表达式将匹配这些。
(?<=[0-9])(.)(?=[0-9])
()
创建一个组来匹配,它是一个捕获组。
?<=
是正向后视,它匹配主表达式之前的组,但不将其包含在结果中
[0-9]
是字符集,匹配0到9之间的任何字符。
.
匹配除换行符以外的任何字符
?=
是一个积极的向前看,它匹配主表达式之后的一个组,而不将其包含在结果中
我建议使用 Regexr 来测试和学习正则表达式。
这个 RegEx 怎么样:(?<=(^|\n)[^-]*-[^-]*)-
?
或作为完整命令(使用 Replace Part of File Name Powershell 的答案):
Get-ChildItem | Rename-Item -NewName {$_.name -replace '(?<=^[^-_]+-[^-_]+)-','_'}
您可以在 -
的前两次出现处拆分字符串,然后通过 -
和 _
:
将它们连接起来
$name = '01A-50-02A-50-CIPP-PRE.MP4'
$first,$second,$rest = $name -split '-',3
$newName = "${first}-${second}_${rest}"
在正则表达式中使用 -replace
运算符:
Get-ChildItem |
Rename-Item -NewName { $_.Name -replace '^([^_-]+-[^_-]+)-', '_' } -WhatIf
-WhatIf
预览重命名操作;删除它以执行实际重命名。
正则表达式 '^([^_-]+-[^_-]+)-'
使用捕获组 ((...)
) 捕获除第二个 -
.
之外的标记
[^_-]+
捕获既不是 -
也不是 _
的任何非空 运行 字符。 _
也被排除,以防止文件名已经 是 正确的误报;对于那些,不排除 _
将匹配第一个 3 标记并在那里插入一个 additional _
。
替换操作数 _
然后使用第一个(也是唯一一个)捕获组 (</code>) 的值,后跟文字 <code>_
来替换正则表达式匹配,有效地将第二个 -
替换为 _
.
如果给定的文件名与正则表达式不匹配(如果它已经是正确的),则该名称按原样返回,这在 [= 的上下文中是一个安静的空操作29=].
谢谢 Solomon Ucko!
这几乎正是我要找的。
获取子项 |重命名项目 -NewName {$.name -replace '(?<=(^|\n)[^-]*-[^-]*)-',''}
它在我可以抛出的所有示例上都非常有效,除了...
如果我 运行 将代码放在错误命名和正确命名文件的混合组上,它会在不属于它的地方添加另一个下划线...
"E21U-50A_E21U_50-CIPP-PST-CMP"
而不是
"E21U-50A_E21U-50-CIPP-PST-CMP"
解决这个问题很简单。
我所做的只是首先将所有 _
替换为 -
。
Get-ChildItem | Rename-Item -NewName {$_.name -replace '_','-'}
Get-ChildItem | Rename-Item -NewName {$_.name -replace '(?<=(^|\n)[^-]*-[^-]*)-','_'}
感谢所有有其他想法的人。诚然,我还没有尝试过它们,因为这个解决方案是我尝试的第一个解决方案,并且成功了。
但是,我将在完成工作后修改其他解决方案。
再次感谢。
我一直在使用 Powershell 来简化创建目录、重命名和移动文件等重复性任务。我正在处理视频和 PDF 文件,其中所需的文件名语法非常具体。到目前为止,我已经能够纠正我遇到的所有常见错误 运行,但是这个错误让我很困惑。
我的文件的正确语法包括:
01A-50_02A-50-CIPP-PRE.MP4
01AA-50_02AA-50-CIPP-PNSL.PDF
W01AA-48_02AA-48-CIPP-PST-CMP.MPG
我收到了大量如下所示的文件:
01A-50-02A-50-CIPP-PRE.MP4
01AA-50-02AA-50-CIPP-PNSL.PDF
W01AA-48-02AA-48-CIPP-PST-CMP.MPG
我需要用下划线替换第二个破折号,同时保持其他破折号不受影响。否则我可以在 excel 的帮助下批量执行此操作,但我希望有一个简短的代码可以找到并更正此语法错误,而无需将列表导出到 excel,使用文本到列,然后将字母数字部分连接在一起。我也不想手动更正所有这些文件名。
根据我的研究,不可能针对特定字符的出现进行替换。我最接近的想法是我找到了一个涉及 REGEX 以及识别和替换模式的解决方案。我没能对此做任何有建设性的事情。
我使用此代码的方式是打开包含命名错误文件的文件夹,在那里打开 Powershell window,从我桌面上的 txt 文件复制代码,然后将其粘贴到 Powershell .
如有任何帮助,我们将不胜感激。
查看您的示例,似乎第二个 -
总是出现在数字之间。类似于 $Variable -replace 'REGEX','_'
使用下面的正则表达式将匹配这些。
(?<=[0-9])(.)(?=[0-9])
()
创建一个组来匹配,它是一个捕获组。
?<=
是正向后视,它匹配主表达式之前的组,但不将其包含在结果中
[0-9]
是字符集,匹配0到9之间的任何字符。
.
匹配除换行符以外的任何字符
?=
是一个积极的向前看,它匹配主表达式之后的一个组,而不将其包含在结果中
我建议使用 Regexr 来测试和学习正则表达式。
这个 RegEx 怎么样:(?<=(^|\n)[^-]*-[^-]*)-
?
或作为完整命令(使用 Replace Part of File Name Powershell 的答案):
Get-ChildItem | Rename-Item -NewName {$_.name -replace '(?<=^[^-_]+-[^-_]+)-','_'}
您可以在 -
的前两次出现处拆分字符串,然后通过 -
和 _
:
$name = '01A-50-02A-50-CIPP-PRE.MP4'
$first,$second,$rest = $name -split '-',3
$newName = "${first}-${second}_${rest}"
在正则表达式中使用 -replace
运算符:
Get-ChildItem |
Rename-Item -NewName { $_.Name -replace '^([^_-]+-[^_-]+)-', '_' } -WhatIf
-WhatIf
预览重命名操作;删除它以执行实际重命名。
正则表达式
之外的标记'^([^_-]+-[^_-]+)-'
使用捕获组 ((...)
) 捕获除第二个-
.[^_-]+
捕获既不是-
也不是_
的任何非空 运行 字符。_
也被排除,以防止文件名已经 是 正确的误报;对于那些,不排除_
将匹配第一个 3 标记并在那里插入一个 additional_
。
替换操作数
_
然后使用第一个(也是唯一一个)捕获组 (</code>) 的值,后跟文字 <code>_
来替换正则表达式匹配,有效地将第二个-
替换为_
.如果给定的文件名与正则表达式不匹配(如果它已经是正确的),则该名称按原样返回,这在 [= 的上下文中是一个安静的空操作29=].
谢谢 Solomon Ucko! 这几乎正是我要找的。
获取子项 |重命名项目 -NewName {$.name -replace '(?<=(^|\n)[^-]*-[^-]*)-',''}
它在我可以抛出的所有示例上都非常有效,除了... 如果我 运行 将代码放在错误命名和正确命名文件的混合组上,它会在不属于它的地方添加另一个下划线...
"E21U-50A_E21U_50-CIPP-PST-CMP"
而不是
"E21U-50A_E21U-50-CIPP-PST-CMP"
解决这个问题很简单。
我所做的只是首先将所有 _
替换为 -
。
Get-ChildItem | Rename-Item -NewName {$_.name -replace '_','-'}
Get-ChildItem | Rename-Item -NewName {$_.name -replace '(?<=(^|\n)[^-]*-[^-]*)-','_'}
感谢所有有其他想法的人。诚然,我还没有尝试过它们,因为这个解决方案是我尝试的第一个解决方案,并且成功了。
但是,我将在完成工作后修改其他解决方案。
再次感谢。