例如,假设我有file1_6363
,file1_6364
和file1_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 现在捕获一个或多个字符(
.+
),直到下划线匹配。
- 捕获组 1 现在捕获一个或多个字符(
顺便说一句,无论你使用什么方法操作字符串-Path
,Rename-Item
cmdlet 可以接受管道输入,从而无需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