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
有没有办法使S和E大写

  • 名称S01E01.mp4
  • 名称S01E02.mp4
  • 名称S01E03.mp4
我尝试了以下方法,但它取代了所有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
}
  • 名称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
    e
    都已大写,则替换为有效的no op;但是,如果其中一个或两个都是小写,则替换将确保它们是大写的


要将所有这些放在一起,请使用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
      而不是
      -Path
      参数也会匹配所有文件名,因为此时解释通配符表达式的是Windows API,而不是PowerShell,并且出于向后兼容性的原因
      *.
      *
      被视为相同
  • 不需要
    foreach
    foreach对象
    )循环,因为
    重命名项
    可以直接接受
    获取子项
    的输出


我正在从文件名导入字符串,因此S00E00将发生更改,有没有办法将字符串分开,或者告诉我的powershell脚本在运行时忽略大小写?具体来说,会发生什么更改?当前答案将任何两位数序列与
\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' }