基于前缀给文件名添加后缀的 Powershell 错误

3

我有一些以jpg格式命名的文件列表,它们位于一个文件夹中:

"1.George ABCD.jpg"
"2.George ABCD.jpg"
"3.Mead ABCD.jpg"

所以我想要做的是将前缀变为后缀,就像这样:
"George ABCD 1.jpg"
"George ABCD 2.jpg"
"Mead ABCD 2.jpg"

我希望它能够递归地通过子文件夹工作。

我尝试过的代码片段如下:

ls -Recurse |? BaseName -match '^(\d+\.)([^0-9].*)$' |ren -new {"{0}{1}{2}" -f $matches[2],' ', $matches[1].substring(0,1)+ $_.extension}
cmd /c pause

现在的问题是,我的代码目前无法处理双数位的名称,例如:

"11.George ABCD.jpg"

相反它所做的是喷出

"George ABCD 1.jpg"

这并不是我想要的,我知道它与正则表达式d+有关,该表达式表示一个或多个数字,但我不确定我应该使用什么来使它对一个或多个数字起作用。

也就是说,我希望将“11.George ABCD.jpg”的输出改为“George ABCD 11.jpg”。

有没有办法可以解决这个问题?


1
一个非正则表达式的方法是在点上分割.BaseName,修整项目,用任何所需的分隔符按所需顺序连接它们,最后从它们中制作一个文件名以在调用Rename-Item时使用。[咧嘴笑] - Lee_Dailey
2个回答

6
这是因为$matches[1].substring(0,1)。你总是只使用匹配到的第一个数字。如果修改正则表达式中的第一组,并不使用后面的substring,你就可以得到想要的结果:
ls -Recurse |? BaseName -match '^(\d+)\.([^0-9].*)$' |ren -new {"{0}{1}{2}" -f $matches[2],' ', $matches[1] + $_.extension}

啊,是的,这就是我在寻找的,谢谢。所以应该把"."移到括号外面,这样它就不是$matches[1]的一部分了,谢谢,这很有道理。我一开始尝试使用子字符串是因为我最初将点包含在$matches[1]中,但这是一个更优雅的解决方案。 - John Smith

6

这是我的做法

Get-ChildItem -File -Recurse | ForEach-Object {
    $newname = $_.Name -replace '^(\d+)\.?\s*(.*)(\.jpg)$', '$2 $1$3'
    if ($newname -ne $_.Name) { $_ | Rename-Item -New $newname }
}

这种方法并不一定比你的方法更好,但它的构造更简单,并且换行更漂亮。

注意替换字符串周围的单引号,它们是必须的(否则PowerShell会试图获取$)。


也可以正常工作,您介意我问一下-replace吗?对于“$2 $1$3”,中间的空格是必要的吗?会有什么影响吗? - John Smith
1
@JohnSmith 你想在文件名的文本部分和数字之间加一个空格,所以是的,这个空格是必要的。(你在 "{0}{1}{2}" -f $matches[2],' ', $matches[1]... 中的 ' ' 做了同样的事情。) - Tomalak

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接