【问题标题】:Getting an Error when I try to change file name in PowerShell当我尝试在 PowerShell 中更改文件名时出现错误
【发布时间】:2016-01-16 02:19:45
【问题描述】:

我在网上找到了与这些类似的命令。我想将文件名中的括号替换为空格或空字符串。

我尝试更改的文件如下所示:

Nehemiah (1).mp3
Nehemiah (2).mp3
Nehemiah (11).mp3

我真的希望它们看起来像下面这样:

Nehemiah 01.mp3
Nehemiah 02.mp3
Nehemiah 11.mp3

这是我尝试过的脚本。

Dir | Rename-Item –NewName { $_.name –replace “(“,”” }
Dir *.mp3 | rename-item -newname {  $_.name  -replace " ("," "  }

这些都不起作用。

这是我收到的错误消息。

Rename-Item :参数“NewName”的脚本块的输入 失败的。正则表达式模式 ( 无效。在 line:1 字符:34 + 目录 *.mp3 |重命名项目 -newname { $_.name -replace " ("," " } + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + CategoryInfo : InvalidArgument: (C:\Users...ehemiah (1).mp3:PSObject) [Rename-Item],参数 ndingException + FullyQualifiedErrorId : ScriptBlockArgumentInvocationFailed,Microsoft.PowerShell.Commands.RenameItemCommand

【问题讨论】:

  • -replace 需要正则表达式模式,您需要转义 (: -replace [regex]::Escape(" (")," "
  • 感谢 Mathias,解决了问题。我想知道是否需要转义括号但我找不到需要转义的字符列表以及如何在线转义它们。我去的网站都没有列出括号。
  • 另外,请选择一个标签。没有批处理文件代码时使用批处理文件。

标签: powershell


【解决方案1】:

正如您在 Mathias R Jessen 的 cmets 中看到的那样,-replace 支持正则表达式,您需要考虑这一点。静态方法Escape 可以帮助自动转义字符串中的正则表达式元字符,以便看起来更具可读性和功能。

我确实设法找到this on MSDN 谈论使用[regex]::escape() 转义的字符:

通过将一组最小字符(\、*、+、?、|、{、[、(,)、^、$、.、# 和空格)替换为它们的转义码来转义它们。这指示正则表达式引擎按字面意思解释这些字符,而不是元字符。

但是,由于您实际上不需要在这里使用正则表达式,我建议您使用字符串方法.replace(),因为这样可以在没有额外开销的情况下完成相同的操作。

Get-ChildItem "*.mp3" | Rename-Item -NewName {($_.name).Replace(" ("," ")}

字符填充改变了一些东西。我会在那里选择正则表达式,因为拆分字符串并将它们重新组合在一起要容易得多。

Get-ChildItem "*.mp3" | 
    Where-Object{$_.name -match "\((\d+)\)"}
    Rename-Item -NewName {
        [regex]::Replace($_.Name,"\((\d+)\)",{param($match) ($match.Groups[1].Value).PadLeft(2,"0")})
    }

感谢PetSerAl for helping with this backreference replacement 解决方案。

【讨论】:

  • 刚注意到垫左要求。
  • 伟大的思想都一样吗?这看起来与我的代码非常相似。 :)
  • @rojo 正则表达式和像这样的简单示例都会发生这种情况.....这就是为什么我赞成你的帖子。当我看到 sls 之类的东西时,它会变得不必要地复杂。
  • 我明白了。好吧,您对自己的研究进行了更多研究。我会回报的。
  • @rojo 我太专注于正则表达式部分。真的填充不是问题的一部分.....我对它很感兴趣。
【解决方案2】:

我确信这可能可以用更简单的方式完成,但它对我有用。

[regex]$rxp = '\((\d+)\)'; gci | ?{$_.Name -match $rxp} | %{ ren $_.FullName ($_.name -replace $rxp, $matches[1].padLeft(2,'0')) }

这是一个细分:

# Define regex.  The outer parentheses are literal.  The inner are a
# capture group, capturing the track number in the filename.

[regex]$rxp = '\((\d+)\)'

# Get-ChildItems.  For each child item that matches the regex...

gci | ?{$_.Name -match $rxp} | %{

    # Rename the file, replacing the offending regex match with the match
    # obtained from the where-object selector (the ? block)

    ren $_.FullName ($_.name -replace $rxp, $matches[1].padLeft(2,'0'))
}

PowerShell 无法轻松处理反向引用捕获的数据。但是,-match 运算符填充了一个 $matches 数组,可以更轻松地进行操作。

这不仅可以删除括号,还可以将您的个位数数字补零。

【讨论】:

    【解决方案3】:

    试试这个。

    ls | Where {$_.FullName -match '(-)'} | Rename-Item -NewName { $_ -replace ("-","_") }
    

    我列出了目录中匹配(包含)破折号- 的每个文件,然后我用new-name- 替换为下划线_ 将其导入Rename-Item

    PS:好处是,我可以快速把下划线的破折号放回去。

    【讨论】:

      猜你喜欢
      • 2011-07-12
      • 2011-06-02
      • 2020-03-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-06-04
      • 2022-11-21
      相关资源
      最近更新 更多