我有一些数据文件,其文件名中包含需要删除的文本。每个文件名的名称都有几个下划线,具体取决于文件名的长度。我的目标是删除.pdf
文件扩展名和最后一个_
之间存在的文本。
例如,我有:
并希望删除大胆的部分成为:
我是powershell的新手,但我做了一些研究,发现Powershell - Rename filename by removing the last few characters问题很有帮助,但它并没有让我得到我需要的东西,因为我不能硬编码要删除的字符长度,因为它们可能有不同的长度(2-4)
Get-ChildItem 'C:\Path\here' -filter *.pdf | rename-item -NewName {$_.name.substring(0,$_.BaseName.length-3) + $_.Extension}
似乎可能有一种方法可以使用.split
或regex
这样做,但我无法找到解决方案。谢谢。
您可以使用LastIndexOf()
类的[string]
方法来获取字符最后一个实例的索引。在你的情况下,这应该这样做:
Get-ChildItem 'C:\Path\here' -filter *.pdf | rename-item -NewName { $_.BaseName.substring(0,$_.BaseName.lastindexof('_')) + $_.Extension }
使用-replace
operator和regex可以实现简洁的解决方案:
Get-ChildItem 'C:\Path\here' -Filter *.pdf |
Rename-Item -NewName { $_.Name -replace '_[^_]+(?=\.)' } -WhatIf
-WhatIf
预览重命名操作。删除它以执行实际重命名。
_[^_]+
匹配一个_
字符,后跟一个或多个非_
字符([^-]
)
如果您想更具体地匹配(十进制)数字(\d
),请改用_\d+
。(?=\.)
是一个look-ahead assertion((?=...)
),与文字.
(\.
)匹配,即文件扩展名的开头,不包括在比赛中。-replace
提供替换操作数,它隐含地是替换匹配的空字符串,这有效地删除了文件扩展名之前的最后一个_
前缀标记。您还可以通过处理带有“双”扩展名的文件名来使正则表达式更加健壮;例如,上述解决方案将用a_bc.d_ef.pdf
替换文件名a.c.pdf
,即执行两次替换。为防止这种情况,请改用以下正则表达式:
$_.Name -replace '_[^_]+(?=\.[^.]+$)'
前瞻断言现在确保只有最后一个扩展匹配:字符串.
(\.
)后跟一个或多个(+
)字符,而不是文字.
([^.]
,一个否定字符集([^...]
))在字符串的末尾($
)。
只是为了展示另一种选择,
Name
中删除的部分是与BaseName
分离的_
中的最后一个元素[-1]
的负面指数Get-ChildItem 'C:\Path\here' -Filter *.pdf |%{$_.BaseName.split('_\d+')[-1]} 6 10 101
_
时,必须再次应用它才能将其移除。Get-ChildItem 'C:\Path\here' -Filter *.pdf |
Rename-Item -NewName { $_.Name -replace '_'+$_.BaseName.split('_')[-1] } -whatif
编辑修改后的变体,它在下划线处拆分BaseName
没有删除分裂字符使用-split
运算符和
一个带有zero length lookahead的RegEx
> Get-ChildItem 'C:\Path\here' -Filter *.pdf |%{($_.BaseName -split'(?=_\d+)')[-1]}
_6
_10
_101
Get-ChildItem 'C:\Path\here' -Filter *.pdf |
Rename-Item -NewName { $_.Name -replace ($_.BaseName -split'(?=_)')[-1] } -whatif