【发布时间】:2020-07-16 09:36:02
【问题描述】:
我想以 yyyymmdd_SequenceNumber 格式重命名特定文件夹中的所有 .jpg 文件,以便在 yyyy 和 mm 之后包含下划线。因此,例如,名为 20200712_123456.jpg 的文件将重命名为 2020_07_12_123456.jpg。应该适用于文件夹中的所有 .jpg 文件,最好也适用于所有 .mp4 文件。以下代码几乎可以工作,只是第一个 .jpg 文件名更改为 2020__07_12_123456.jpg(注意双下划线)。所有其他文件都被重命名了。
Get-ChildItem -Path 'C:\test' -Filter '*.jpg' |
ForEach-Object { $_ | Rename-Item -NewName {$_.BaseName.insert(4,'_').insert(7,'_') + $_.Extension}}
奇怪的是下面的代码确实有效,但我读过一些文章说使用 -Include 的结果可能是不可预测的:
Get-ChildItem -Path 'C:\test\*' -Include *.jpg, *.mp4 |
ForEach-Object { $_ | Rename-Item -NewName {$_.BaseName.insert(4,'_').insert(7,'_') + $_.Extension}}
我更像是一个批处理脚本人,但我正在尝试使用 Powershell。 提前感谢您的帮助。
【问题讨论】:
-
您使用的是
-NewName { ... },而不是-NewName "$( ... )"或-NewName ( ... )。那将传递一个ScriptBlock,而不是String,给那个参数。我以前从未见过这种情况,并且会质疑这是否有效,但是……显然它几乎可以。 -
第一个文件在重命名之前的位置 4 是否已经有下划线?
-
@BACON 是延迟脚本绑定,它应该适用于任何接受管道输入的参数。
-
@AdminOfThings 是的,刚刚在
about_Script_Blocks中找到了。不过,它似乎在这里没有提供任何优势,是吗?如果我理解的话,它将允许将Get-ChildItem直接通过管道传输到Rename-Item,但在ForEach-Object内部它与"$( ... )"或( ... )相同。 -
对我来说,在 PowerShell 5.1 中,第一个文件
20200712_123456.jpg被重命名为2020__0_7_12_123456.jpg(两个 额外的下划线),而在 7.0.2 中它正确地变为 @987654337 @。如果我更改为Get-ChildItem ... | ForEach-Object { $_.BaseName.insert(4,'_').insert(7,'_') + $_.Extension },它将在 5.1 上输出正确的文件名。Get-ChildItem ... | Rename-Item -NewName {$_.BaseName.insert(4,'_').insert(7,'_') + $_.Extension}两个版本的行为相同:5.1 上有额外的下划线,但 7.0.2 没有。
标签: powershell