【问题标题】:Rename multiple files with special characters in filenames用文件名中的特殊字符重命名多个文件
【发布时间】:2018-12-30 07:03:03
【问题描述】:

尝试从同一目录中的大量文件中删除前几个字符,但文件名中的特殊字符出现问题。我还需要使用通配符来指定要删除的文本,因为该文本可能包含一位或两位数字。

我是使用 v2.0.1.1 的新手。

一个示例文件名是

(2) S17- 22429 E1_[49946,12147]_composite_image.jpg

我需要删除括号中的初始数字以及以下空格。括号中的数字可能是一位或两位数,因此需要通配符。

生成的文件名应该是:

S17- 22429 E1_[49946,12147]_composite_image.jpg

所有文件都将包含由方括号中的“,”分隔的坐标,并且所有文件都是 .jpg,但最终名称中的其他所有内容都会有所不同。

一直在阅读各种关于问题点点滴滴的文章,尝试了下面的代码。

问题似乎与方括号和逗号有关,但只有我能找到的技术(``[ 等)告诉你如何在搜索字符串中处理它们,而不是在你所在的字符串部分不感兴趣。-literalpath 似乎也没有帮助。

dir | rename-item -NewName { ($_.name) -Replace("\(*\) ","")}

并且已经尝试了对这个基本代码的各种修改。

遍历每个文件,但都包含:

Rename-Item : Cannot rename because item at 'Microsoft.PowerShell.Core\FileSystem::C:\...\(2) S17- 22429 E1_[49946,12147]_composite_image.jpg' does not exist.
At line:1 char:19
+ dir | rename-item <<<<  -NewName { ($_.name) -Replace("\(*\) ","")}
    + CategoryInfo          : InvalidOperation: (:) [Rename-Item], PSInvalidOperationException
    + FullyQualifiedErrorId : InvalidOperation,Microsoft.PowerShell.Commands.RenameItemCommand

【问题讨论】:

    标签: powershell substring wildcard file-rename


    【解决方案1】:

    无需复杂的powershell脚本,只需简单的CMD即可。

    这将重命名具有 1 个长度编号的文件:

    for %a in ("(?) *.*") do ren "%a" "////*.*"
    

    这是一个长度为 2 的数字:

    for %a in ("(??) *.*") do ren "%a" "/////*.*"
    

    你可能会想这样做:

    for %a in ("(*) *.*") do ren "%a" "////*.*"
    

    但是如果文件名有 2 个以上的长度数字,那么文件名的开头就会有空格。

    它是如何工作的?

    让我们先看看重命名: 所以如果你有这个文件名:(2) S17- 22429 E1_[49946,12147]_composite_image.jpg,我们要做的是:

    ren "(?) S17- 22429 E1_[49946,12147]_composite_image.jpg" "////*.*";
    

    ? 问号表示任意一个长度字符。 * 星号表示任何 许多 字符。 / 表示丢弃这一个字符。

    所以(2) S17- 22429 E1_[49946,12147]_composite_image.jpg => S17- 22429 E1_[49946,12147]_composite_image.jpg

    对于 2 个长度的数字,您需要两个 ??和五个 ///// 像这样:

    ren "(??) S17- 22429 E1_[49946,12147]_composite_image.jpg" "/////*.*";
    

    我们在) 之后使用空格,因此模式匹配更严格。

    然后我们使用:

    for %a in (`condition`) do `command`
    

    它对每个处于条件的文件进行迭代,然后执行命令。 %a 是一个特殊的通配符,您可以在命令中使用它来获取文件名。

    所以基本上,我们对每个文件所做的是,重命名丢弃前 4 或 5 个字符,然后使用 ?在条件中,所以我们得到所有匹配模式的文件。

    瞧,您也可以根据需要进行调整。

    【讨论】:

      【解决方案2】:

      看起来重命名项目确实存在特殊字符问题。当 Cmdlet 失败时,寻找对象方法通常是个好主意。试试这个。它适用于 PS 5.1

      gci *.jpg | % {
        $_.MoveTo("$($_.DirectoryName)\$($_.Name -replace '\(.*\) ','')")
      }
      

      【讨论】:

        【解决方案3】:

        如果我这样做对我有用:

        Get-ChildItem -Path 'D:\' -Filter '*.jpg' | 
            ForEach-Object { $_ | Rename-Item -NewName ($_.Name -replace '^\(\d+\)\s*', '')}
        

        这是假设文件名总是以括号之间的数字开头。如果它可以是这些括号之间的任何字符(甚至没有),请执行($_.Name -replace '^\(.*\)\s*', '')


        编辑

        显然,通过管道重命名多个文件需要Rename-Item的语法为脚本块,如the docs中的第四个示例所示。

        如果你这样做:

        Get-ChildItem -Path 'D:\' -Filter '*.jpg' | Rename-Item -NewName { $_.Name -replace '^\(\d+\)\s*', '' }
        

        它有效。
        所以,除了两件事,你几乎做对了:

        • 您已将圆括号添加到 -replace 参数中
        • 您已在左括号后直接添加了正则表达式量词 *,因此基本上您的正则表达式要求零个或多个 ( 字符,而不是文件名中括号之间的任何字符

        希望有帮助

        【讨论】:

          猜你喜欢
          • 2017-11-13
          • 1970-01-01
          • 1970-01-01
          • 2015-02-09
          • 2016-05-16
          • 1970-01-01
          • 2014-05-12
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多