Powershell在文件扩展名和下划线之前删除Text Between

问题描述 投票:1回答:3

我有一些数据文件,其文件名中包含需要删除的文本。每个文件名的名称都有几个下划线,具体取决于文件名的长度。我的目标是删除.pdf文件扩展名和最后一个_之间存在的文本。

例如,我有:

  • AB_NAME_NAME_NAME_NAME_DS_123_EN_6.pdf
  • AC_NAME_NAME_NAME_DS_321_EN_10.pdf
  • AD_NAME_NAME_DS_321_EN_101.pdf

并希望删除大胆的部分成为:

  • AB_NAME_NAME_NAME_NAME_DS_123_EN.pdf
  • AC_NAME_NAME_NAME_DS_321_EN.pdf
  • AD_NAME_NAME_DS_321_EN.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}

似乎可能有一种方法可以使用.splitregex这样做,但我无法找到解决方案。谢谢。

powershell
3个回答
2
投票

您可以使用LastIndexOf()类的[string]方法来获取字符最后一个实例的索引。在你的情况下,这应该这样做:

Get-ChildItem 'C:\Path\here' -filter *.pdf | rename-item -NewName { $_.BaseName.substring(0,$_.BaseName.lastindexof('_')) + $_.Extension }

1
投票

使用-replace operatorregex可以实现简洁的解决方案:

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 '_[^_]+(?=\.[^.]+$)'

前瞻断言现在确保只有最后一个扩展匹配:字符串.\.)后跟一个或多个(+)字符,而不是文字.[^.],一个否定字符集([^...]))在字符串的末尾($)。


0
投票

只是为了展示另一种选择,

  • 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
© www.soinside.com 2019 - 2024. All rights reserved.