使用 Powershell 删除文件名中字符串第二次出现后的所有后续字符
Remove all following characters after the second occurence of a string in a filename with Powershell
在我的音乐库中,我有这样的文件名:
- 艺术家 - 歌曲(feat.OtherArtist)(feat.OtherArtist).mp4
- 艺术家 - 歌曲(feat.OtherArtist)(电台编辑)(feat.OtherArtist).mp4
我想要的是删除最后提到的重复功能。这是我到目前为止想出的:
Get-ChildItem -Path "path" -Recurse -Filter *feat*feat* | ForEach-Object { $_ | Rename-Item -NewName $_.Name.SubString(0,$_.Name.Length -10) }
这会获取所有具有重复特征的文件,然后只删除最后 10 个字符(不幸的是包括文件扩展名),如果这首歌有多个艺术家或什至名字更长的艺术家,这将无法正常工作。
我想为此我需要正则表达式,但我在使用 Powershell 方面最多还是个初学者,所以非常感谢您的帮助。
RegEx确实可以为所欲为。您只需要做一些与您在第一个过滤器中所做的非常相似的事情。这是神奇的字符串:
(.*feat.*?)(\s*\(?feat.*\)\s*)(\..+)
您可以像这样使用它(完全跳过 ForEach
循环):
Get-ChildItem -Path .\* -Recurse -Filter *feat*feat* | Rename-Item -NewName {$_.Name -replace '(.*feat.*?)(\s*\(?feat.*\)\s*)(\.[^\.]+)',''}
下面是该字符串的分解方式及其作用:
(.*feat.*)(\s\(feat.*\)\s*)(\.[^\.]+)
第一俘虏小组(壮举)
.匹配任何字符(行终止符除外)
* 在零次和无限次之间匹配前面的令牌,尽可能多次,根据需要回馈(贪心)
feat 按字面匹配字符 feat(区分大小写)
.匹配任何字符(行终止符除外)
*?在零次和无限次之间匹配前一个标记,尽可能少,根据需要扩展(惰性)
第二个捕获组 (\s(feat.)\s)
\s 匹配任何空白字符(相当于 [\r\n\t\f\v ])
* 在零次和无限次之间匹配前面的令牌,尽可能多次,根据需要回馈(贪心)
( 匹配字符 ( 字面上(区分大小写)
?在零到一次之间匹配前一个标记,尽可能多次,根据需要回馈(贪婪)
feat 按字面匹配字符 feat(区分大小写)
.匹配任何字符(行终止符除外)
* 在零次和无限次之间匹配前面的令牌,尽可能多次,根据需要回馈(贪心)
) 按字面匹配字符 ) (区分大小写)
\s 匹配任何空白字符(相当于 [\r\n\t\f\v ])
* 在零次和无限次之间匹配前面的令牌,尽可能多次,根据需要回馈(贪婪)
第3捕获组(\.[^\.]+)
\.匹配字符 .字面意思(区分大小写)
匹配下面列表中不存在的单个字符 [^\.]
+ 在一次和无限次之间匹配前一个令牌,尽可能多次,根据需要回馈(贪婪)
看到它在这里工作(我从那里得到字符串分解,但格式更好):https://regex101.com/r/FWlNLi/1
在我的音乐库中,我有这样的文件名:
- 艺术家 - 歌曲(feat.OtherArtist)(feat.OtherArtist).mp4
- 艺术家 - 歌曲(feat.OtherArtist)(电台编辑)(feat.OtherArtist).mp4
我想要的是删除最后提到的重复功能。这是我到目前为止想出的:
Get-ChildItem -Path "path" -Recurse -Filter *feat*feat* | ForEach-Object { $_ | Rename-Item -NewName $_.Name.SubString(0,$_.Name.Length -10) }
这会获取所有具有重复特征的文件,然后只删除最后 10 个字符(不幸的是包括文件扩展名),如果这首歌有多个艺术家或什至名字更长的艺术家,这将无法正常工作。
我想为此我需要正则表达式,但我在使用 Powershell 方面最多还是个初学者,所以非常感谢您的帮助。
RegEx确实可以为所欲为。您只需要做一些与您在第一个过滤器中所做的非常相似的事情。这是神奇的字符串:
(.*feat.*?)(\s*\(?feat.*\)\s*)(\..+)
您可以像这样使用它(完全跳过 ForEach
循环):
Get-ChildItem -Path .\* -Recurse -Filter *feat*feat* | Rename-Item -NewName {$_.Name -replace '(.*feat.*?)(\s*\(?feat.*\)\s*)(\.[^\.]+)',''}
下面是该字符串的分解方式及其作用:
(.*feat.*)(\s\(feat.*\)\s*)(\.[^\.]+)
第一俘虏小组(壮举)
.匹配任何字符(行终止符除外)
* 在零次和无限次之间匹配前面的令牌,尽可能多次,根据需要回馈(贪心)
feat 按字面匹配字符 feat(区分大小写)
.匹配任何字符(行终止符除外)
*?在零次和无限次之间匹配前一个标记,尽可能少,根据需要扩展(惰性)
第二个捕获组 (\s(feat.)\s)
\s 匹配任何空白字符(相当于 [\r\n\t\f\v ])
* 在零次和无限次之间匹配前面的令牌,尽可能多次,根据需要回馈(贪心)
( 匹配字符 ( 字面上(区分大小写)
?在零到一次之间匹配前一个标记,尽可能多次,根据需要回馈(贪婪)
feat 按字面匹配字符 feat(区分大小写)
.匹配任何字符(行终止符除外)
* 在零次和无限次之间匹配前面的令牌,尽可能多次,根据需要回馈(贪心)
) 按字面匹配字符 ) (区分大小写)
\s 匹配任何空白字符(相当于 [\r\n\t\f\v ])
* 在零次和无限次之间匹配前面的令牌,尽可能多次,根据需要回馈(贪婪)
第3捕获组(\.[^\.]+)
\.匹配字符 .字面意思(区分大小写)
匹配下面列表中不存在的单个字符 [^\.]
+ 在一次和无限次之间匹配前一个令牌,尽可能多次,根据需要回馈(贪婪)
看到它在这里工作(我从那里得到字符串分解,但格式更好):https://regex101.com/r/FWlNLi/1