Powershell 在文件名中间对字母进行大写
我正在寻找一种方法来调整以下内容:Powershell 在文件名中间对字母进行大写,powershell,Powershell,我正在寻找一种方法来调整以下内容: 名称S01e01.mp4 名称s01e02.mp4 名称s01e03.mp4 有没有办法使S和E大写 名称S01E01.mp4 名称S01E02.mp4 名称S01E03.mp4 我尝试了以下方法,但它取代了所有E,结果是: dir -recurse | where {-Not $_.PsIscontainer -AND $_.name -match "."} | foreach { $New=$_.Basename.Replace(" s"," S
- 名称S01e01.mp4
- 名称s01e02.mp4
- 名称s01e03.mp4
- 名称S01E01.mp4
- 名称S01E02.mp4
- 名称S01E03.mp4
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
}
- 名称S01E01.mp4
- 名称S01E02.mp4
- 名称S01E03.mp4
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的建议后得到的,看起来几乎没有什么变化
谢谢您的方法不起作用,因为
[string]
类型的.Replace()
方法总是替换所有(文本)匹配项
相反,请使用PowerShell的-replace
运算符,该运算符基于正则表达式(以单个文件名为例):
有关-replace
行为的简明摘要,请参阅我的
注:
- 为简单起见,上面的正则表达式设计为匹配整个文件名,包括扩展名;因此,在问题中发布的代码上下文中,该行需要为:
$New=$\.Name-替换“(.*\b)s(\d{2})e(\d{2}\b.*)”,$1S$2E$3”
与-replace
相同;也就是说,匹配不区分大小写。因此,如果所讨论的-ireplace
和s
都已大写,则替换为有效的no op;但是,如果其中一个或两个都是小写,则替换将确保它们是大写的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
请求目录)-Directory
,因为(隐含的)*.*
参数只匹配至少包含一个句点(-Path
)的文件名,我认为这是您的意图;与此相反,您尝试对
执行相同的操作将匹配所有文件名,因为正则表达式中的元字符-match'.
表示任何单个字符- 另一方面,将
传递到*.
而不是-Filter
参数也会匹配所有文件名,因为此时解释通配符表达式的是Windows API,而不是PowerShell,并且出于向后兼容性的原因-Path
与*.
被视为相同*
- 另一方面,将
- 不需要
(foreach
)循环,因为foreach对象
可以直接接受重命名项
的输出获取子项
\d{2}
匹配。我不知道你说的第二句话是什么意思。当我用你的行代替我的$New时,它会删除扩展名,并且不会更改任何内容,所以我想我不知道如何将你的行合并到我上面的现有代码中。@DefcaTrick:请查看我的更新。前面的正则表达式不起作用,因为您悄悄地改变了问题的前提:原始示例文件名在s\d{2}e\d{2}
子字符串之前有一个空格,而您后来添加的示例命令中的文件名有一个句点。我已经将正则表达式推广到使用\b
在单词边界处进行匹配,这应该涵盖这两种情况。请注意,提供具有代表性的样本输入非常重要,包括对可能发生的变化的描述。最后,请参见底部整体命令的简化版本。
Get-ChildItem *.* -Recurse -File |
Rename-Item -NewName { $_.Name -replace '(.*\b)s(\d{2})e(\d{2}\b.*)', '$1S$2E$3' }