Powershell脚本,用于在文件名中间大写一个字母

时间:2018-01-26 03:35:48

标签: powershell

我正在寻找一种方法来调整以下内容:

  • 姓名S01e01.mp4
  • 姓名s01e02.mp4
  • 姓名s01e03.mp4

有没有办法将S和E大写?

  • 姓名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
}
  • NamE S01E01.mp4
  • NamE S01E02.mp4
  • NamE 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的建议后得到的,它几乎看起来没什么变化?

由于

1 个答案:

答案 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- 不敏感。因此,如果所讨论的se都已大写,则替换是有效的无操作;但是,如果其中一个或两个都是小写的,则替换确保它们是大写的。

将所有内容放在一起,使用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的输出。