如何使用 Powershell 重命名文件夹以将年份放在首位
How to rename folders to put the year first using Powershell
我正在尝试整理一些分成许多不同文件夹的旧照片。所有文件夹名称都包含年份,但几乎总是在文件夹名称的末尾。当我试图对过去 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"
}
感谢任何帮助!
如果使用 -match
operator with a regex that captures the name parts of interest via capture groups ((...)
), you can rearrange these name parts, as reflected in the automatic $Matches
variable variable, in a 传递给 Rename-Item
调用:
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
common parameter预览操作。一旦您确定该操作将执行您想要的操作,请删除 -WhatIf
。
有关正则表达式及其交互能力的说明,请参阅 this regex101.com page。
注意:以下使用 -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
操作找不到正则表达式匹配时会发生这种情况,因此 returns 按原样输入字符串),它应该是 安静的无操作 ,因为它已经用于 files - 参见 GitHub issue #14903.
我正在尝试整理一些分成许多不同文件夹的旧照片。所有文件夹名称都包含年份,但几乎总是在文件夹名称的末尾。当我试图对过去 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"
}
感谢任何帮助!
如果使用 -match
operator with a regex that captures the name parts of interest via capture groups ((...)
), you can rearrange these name parts, as reflected in the automatic $Matches
variable variable, in a Rename-Item
调用:
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
common parameter预览操作。一旦您确定该操作将执行您想要的操作,请删除 -WhatIf
。
有关正则表达式及其交互能力的说明,请参阅 this regex101.com page。
注意:以下使用 -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
操作找不到正则表达式匹配时会发生这种情况,因此 returns 按原样输入字符串),它应该是 安静的无操作 ,因为它已经用于 files - 参见 GitHub issue #14903.