我有一些混乱的PDF文件,其文件名中包含文本,需要删除。每个文件名的名称中都有多个下划线,具体取决于文件名的长度。我的目标是删除.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
来做到这一点,但我找不到解决方案。谢谢。
答案 0 :(得分:2)
您可以使用srand
类的LastIndexOf()
方法来获取字符最后一个实例的索引。在您的情况下,应该这样做:
[string]
答案 1 :(得分:1)
将-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 '_[^_]+(?=\.[^.]+$)'
预见断言现在确保仅 last 扩展名匹配:文字.
(\.
)后跟一个或多个(+
)字符串<{<1> 末尾处的文字.
([^.]
,否定的字符集([^...]
)以外的其他字符。 {1}}。
答案 2 :(得分:0)
只是为了展示另一种选择,
Name
中删除的部分是由BaseName
拆分的_
中的 last 元素[-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
EDIT (修改后的变体),它在下划线处分割了BaseName
使用-split
运算符和
而不删除分割字符
带有zero length lookahead
> 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