用文件名中的特殊字符重命名多个文件

时间:2018-12-30 07:03:03

标签: powershell substring wildcard file-rename

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

我是使用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

3 个答案:

答案 0 :(得分:0)

不需要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是一种特殊的通配符,您可以在命令上使用它来获取文件名。

所以基本上,我们要做的是对每个文件进行重命名,丢弃前四个或五个字符,然后使用?在这种情况下,我们将获得与该模式匹配的所有文件。

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

答案 1 :(得分:0)

看起来Rename-Item确实存在特殊字符问题。当Cmdlet失败时,寻找对象方法通常是一个好主意。试试这个。它在PS 5.1上对我有效

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

答案 2 :(得分:0)

如果我愿意,可以为我工作:

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参数
  • 您已经在左括号后面直接添加了正则表达式量词*,因此基本上,您的正则表达式要求输入零个或多个(字符,而不是文件名中括号之间的任何字符

希望有帮助