如何使用PowerShell将文件夹重命名为年份在前?

3

我正在尝试整理一些被分散在许多不同文件夹中的旧照片。所有文件夹名称都包含年份,但几乎总是在文件夹名称的末尾。当我试图对过去20年的所有照片进行排序时,这并不起作用。我正在尝试编写一个脚本,可以循环遍历所有文件夹名称并将年份(YYYY)移动到文件夹名称的开头。

当前文件夹:

  • 2012 最好的旅行
  • 2010 拜访亲戚
  • 2017 旅行
  • 2001 旧照片

转换为:

  • 2012 最好的旅行
  • 2010 拜访亲戚
  • 2017 旅行
  • 2001 旧照片

我不是很熟悉powershell,所以我花了几个小时摆弄正则表达式和必要的脚本来筛选正确的文件夹名称子集(以字母开头并包含4位数字年份),但我仍然无法成功重命名这些文件夹。

这是我的脚本:

$folders = Get-ChildItem -Path C:\Users\User\pictures\ | Where-Object { $_.Name -match '^[a-zA-Z].+[0-9]{4}' }
foreach ($folder in $folders) 
        { $folder.Name.Split() | Where {$_ -match "[0-9]{4}"}
            Rename-Item -Path $folder-NewName  "$($Matches[0])_$folder.Name"
}

非常感谢您的帮助!

1个回答

3
如果您使用-match运算符与通过捕获组((...))捕获感兴趣的名称部分的正则表达式,则可以重新排列这些名称部分,如在传递给Rename-Item调用的延迟绑定脚本块中反映的自动$Matches变量变量。
Get-ChildItem -Directory C:\Users\User\pictures |
  Where-Object Name -match '^(.+?) ?\b(\d{4})\b(.*?)$' |
    Rename-Item -WhatIf -NewName { 
      '{0} {1}{2}' -f $Matches.2, $Matches.1, $Matches.3 
    }

注意:上述命令中的-WhatIf常见参数预览操作。一旦确定操作符合要求,请删除-WhatIf
有关正则表达式的解释和交互功能,请参见此regex101.com页面
注意:以下简化使用 -replace 运算符原则上是有效的,但不幸的是,在 PowerShell 7.2.1 中对于所有名称中不包含4位数字或已经以名称开头的目录报告虚假的 源和目标路径必须不同 错误。
# !! Works, but reports spurious errors as of PowerShell 7.2.1
Get-ChildItem -Directory C:\Users\User\pictures
  Rename-Item -WhatIf -NewName { $_.Name -replace '^(.+?) ?\b(\d{4})\b(.*?)$' }

原因是Rename-Item的不幸行为,当尝试将目录重命名为其现有名称时(当-replace操作未找到正则表达式匹配项并因此返回输入字符串时),会抱怨,这应该是一个静默无操作,就像对于文件一样 - 请参见GitHub问题#14903

1
谢谢,@Santiago。感谢你激发我将正则表达式推广到处理名称中的年份,而不仅仅是在末尾 - 请查看我的更新(也从根本上重构了答案)。至于你的正则表达式:请注意,在 [...] 中的 \1 是指具有代码点 1 的 Unicode 字符。鉴于这样的控制字符不太可能成为输入字符串的一部分,[^\1] 实际上等同于 . - mklement0
刚看到这个评论,我以为 [^\1] 带有捕获组意味着 _"匹配任何不是捕获组 1 的内容"_。这里还有一个例子:https://regex101.com/r/BzBAlg/1 - Santiago Squarzon
1
@Santiago,是的,\1 [...] 之外是一个反向引用(仅在所引用的捕获组出现在引用之前时才起作用)。在 [...] 中,它是一个八进制转义序列,通过其代码点编码一个字符;尝试 [char] 27 -match '[\33]'。要 否定 反向引用,请使用负向先行断言;例如:'aa', 'ab' | % { $_ -match '^(a)(?!\1)' } - mklement0
1
我完全明白您的意思,我在捕获组之前使用它。有道理。感谢您的解释! - Santiago Squarzon
1
我在我设置的测试文件夹上测试了这个脚本,它似乎完美地工作了!感谢您的帮助。我曾经苦苦思索如何成功使用$Matches变量,但那绝对是关键。 - Dr Saurus Rex
显示剩余2条评论

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