首页 > 解决方案 > 转换文件名的日期格式

问题描述

我的文件中有日期,但格式对于下游流程不正确。当前格式为 "name_yyyy_mm_dd_HH_mm" 需要为 "name_ddmmyyyyHHmm" 当前格式为 "N999AN__2021_04_14_18_43_.pak" 我需要修改为 N999AN_140420211843.pak

我已经尝试了几件事,但没有改变名称。这是我最近的尝试。我究竟做错了什么?

$items = Get-ChildItem "$LTemp\*.txt"

foreach ($item in $items)
{
    Rename-Item –path $item.Fullname –Newname {("{0}_{1}_{2}_{3}_{4}_{5}" -f $item.name.split('_',6)[0,3,2,1,4,5])+$item.extension}

    write-host "Name is $item"
}

标签: powershell

解决方案


我假设您需要枚举 *.pak 文件,并且预期的输入模式是name__yyyy_mm_dd_HH_mm并且输出模式是name_ddmmyyyyHH_mm. 如果这是错误的,您将不得不修复代码。

也就是说,脚本块并没有像你现在那样工作得很好。您基本上将它们作为值传递,它们并不总是具有固定值。您可能只需要一个组运算符()或子表达式$()

$items = Get-ChildItem "$LTemp\*.pak"

foreach ($item in $items)
{
    Rename-Item –path $item.Fullname –Newname (("{0}_{3}{2}{1}{4}_{5}" -f $item.name.split('_', [StringSplitOptions]::RemoveEmptyEntries))+$item.extension) -WhatIf

    write-host "Name is $item"
}

我在[StringSplitOptions]::RemoveEmptyEntries这里添加是因为您描述的输入模式中有一个双下划线。

不过,就个人而言,我可能会使用带有命名捕获组的正则表达式,因为这样当模式不匹配时,我可能会让 Powershell 抱怨。此外,我倾向于通过管道传输文件对象Rename-Item而不是向其提供对象的问题较少。

$items = Get-ChildItem "$LTemp\*.pak"

$Pattern = '^(?<Name>.+)__(?<Year>\d{4})_(?<Month>\d{2})_(?<Day>\d{2})_(?<Hour>\d{2})_(?<Minute>\d{2})_'
foreach ($item in $items) {
    if ($item.Name -match $Pattern) {
        $NewName = '{0}_{1}{2}{3}{4}_{5}{6}' -f $Matches['Name'], $Matches['Day'], $Matches['Month'], $Matches['Year'], $Matches['Hour'], $Matches['Minute'], $item.Extension
        $item | Rename-Item -NewName $NewName -WhatIf
    }
    else {
        Write-Warning "File '$($item.FullName)' does not match expected filename pattern '$Pattern'."
    }
}

删除-WhatIf参数以实际执行工作。


推荐阅读