我正在寻找一种方法来调整以下内容:
有没有办法将S和E大写?
我已尝试过以下内容,但它取代了所有导致的:
dir -recurse | where {-Not $_.PsIscontainer -AND $_.name -match "."} |
foreach {
$New=$_.Basename.Replace(" s"," S").Replace("e","E")+$_.Extension
Rename-Item -path $_.Fullname -newname $New -passthru
}
提前非常感谢你。
更新:
cd C:\Users\test\Desktop\test
PS C:\Users\test\Desktop\test> dir -recurse | where {-Not $_.PsIscontainer -AND $_.name -match "."} |
>> foreach {
>> $New = $_.Name -replace '(.* )s(\d{2})e(\d{2}\..*)', '$1S$2E$3'
>> Rename-Item -path $_.Fullname -newname $New -passthru
>> }
Directory: C:\Users\test\Desktop\test
Mode LastWriteTime Length Name
---- ------------- ------ ----
-a---- 1/25/2018 2:32 PM 0 Test.Of.Testing.S01e01.this.X264.Mp4
-a---- 1/25/2018 2:32 PM 0 Test.Of.Testing.S01E01.this.X264.Mp4
-a---- 1/25/2018 2:33 PM 0 Test.Of.Testing.S01e31.this.X264.Mp4
-a---- 1/25/2018 2:33 PM 0 Test.Of.Testing.s01E01.this.X264.Mp4
这是我目前在交换mklement0的建议后得到的,它几乎看起来没什么变化?
由于
答案 0 :(得分:1)
您的方法不起作用,因为[string]
类型的.Replace()
方法总是取代所有(文字)匹配。
相反,使用PowerShell的-replace
运算符,它是基于正则表达式的运算符(以单个文件名为例):
> 'Name s01e01.mp4' -replace '(.*\b)s(\d{2})e(\d{2}\b.*)', '$1S$2E$3'
Name S01E01.mp4
有关-replace
行为的简明摘要,请参阅我的this answer。
注意:
为简单起见,上面的正则表达式旨在匹配整个文件名,包括扩展名;因此,在问题中张贴的代码的上下文中,该行必须是:
$New = $_.Name -replace '(.*\b)s(\d{2})e(\d{2}\b.*)', '$1S$2E$3'
-replace
与-ireplace
相同;也就是说,匹配是case- 不敏感。因此,如果所讨论的s
和e
都已大写,则替换是有效的无操作;但是,如果其中一个或两个都是小写的,则替换确保它们是大写的。
将所有内容放在一起,使用PSv3 +语法:
Get-ChildItem *.* -Recurse -File |
Rename-Item -NewName { $_.Name -replace '(.*\b)s(\d{2})e(\d{2}\b.*)', '$1S$2E$3' }
注意:
PSv3 + -File
开关仅Get-ChildItem
返回文件(类似地,您只能{{1}请求目录 }})。
-Directory
因为(隐含的)*.*
参数只匹配包含至少一个句点(-Path
)的文件名,我认为这是你的意图;相比之下,您尝试对.
执行相同操作会与所有文件名匹配,因为正则表达式中的元字符-match '.'
代表任何单个字符。
.
传递给*.*
而不是-Filter
参数也匹配所有文件名,因为它是Windows API它解释了通配符表达式,而不是PowerShell,并且出于向后兼容的原因,-Path
被视为与*.*
相同。不需要*
(foreach
)循环,因为ForEach-Object
可以直接接受Rename-Item
的输出。