如何在特定列范围内移除或删除文件名的指定部分?

如何在特定列范围内移除或删除文件名的指定部分?

例如,假设我有file1_6363file1_6364file1_6365。我只想删除第一个 63,正如您所见,第一个示例中还有另一个 63,到目前为止,我一直在使用这个 PowerShell 命令:

get-childitem *.mp3 | foreach { rename-item $_ $_.Name.Replace("63", "") }

但是正如您所看到的,我不知道如何指定要删除 63 的列,因此它会删除它检测到的任何 63 个组合。

(如果可能的话,我希望使用 PowerShell 来解决问题)

答案1

为了提供另一种更灵活的选择,-Replace运算符可以匹配正则表达式和在替换中使用捕获组。正则表达式中的捕获组通过括在括号中来定义,并在替换字符串中使用语法、、$1等来引用。$2$3

如果选择的唯一标准是位置,则可以使用通配符.以及可选的各种正则表达式来构造量词指定要匹配的字符数:

量词 描述
* 零次或多次。
+ 一次或多次。
? 零次或一次。
{n,m} 至少n,但不会超过 m 次。

您可以明确指定每个通配符或使用量词,因为以下内容是等效的并且可以互换使用:

数数 显式 量词
1 '.' '.{1}'
2 '..' '.{2}'
3 '...' '.{3}'
4 '....' '.{4}'
5 '.....' '.{5}'
6 '......' '.{6}'
ETC。 ETC。 ETC。

因此,对于您的示例, -NewName 脚本块将是:

  • { $_.Name -Replace ( '(.{6})(..)(.*$)' , '$1$3' ) }

    • 团体 句法 捕获
      1 (.{6}) 前六个字符
      2 (..) 接下来的两个字符
      3 (.*$) 到行尾的剩余文本
  • 替换字符串'$1$3'将捕获组 1 和 3 连接起来,从而消除捕获组 2(第 7 和第 8 列)。

但如果名称的初始部分长度是可变的,例如:

  • 文件1_6363
  • 文件12_6364
  • 文件123_6365

您可以将第一个捕获组定义为长度可变,捕获直到下划线 ( _) 的所有内容:

  • { $_.Name -Replace ( '(.+_)(..)(.*$)' , '$1$3' ) }

    • 捕获组 1 现在捕获一个或多个字符(.+),直到下划线匹配。

顺便说一句,无论你使用什么方法操作字符串-PathRename-Itemcmdlet 可以接受管道输入,从而无需ForEach-Object

Get-ChildItem *.mp3 |
   Rename-Item -NewName { $_.Name -Replace ( '(.{6})(..)(.*$)' , '$1$3' ) }

其他参考资料:

答案2

假设您的文件名始终具有相同的长度,您可以通过删除索引 5 和 6 处的字符来重命名它们:

get-childitem *.mp3 | foreach { rename-item "$_" "$($_.Name.Substring(0,5))$($_.Name.Substring(7))" }

代码将每个文件的名称替换为一个新名称,该新名称由旧名称的前 5 个字符创建,并从索引 7 开始与旧名称的字符连接在一起。

答案3

我会寻找第一个指数 _进而消除从那里开始 2 个字符。因此它可以适用于任何带下划线的文件名。

Get-ChildItem *.mp3 | Rename-Item -NewName {$_.Name.Remove($_.Name.IndexOf('_') + 1, 2)}

例子:

PS C:\Users> gci -name
abc_6363.txt
abcde_6364.txt
abcdefg_6365.txt
PS C:\Users> gci | Rename-Item -NewName {$_.Name.Remove($_.Name.IndexOf('_') + 1, 2)}
PS C:\Users> gci -name
abc_63.txt
abcde_64.txt
abcdefg_65.txt

相关内容