【问题标题】:Correct timestamp with PowerShell script after comparison with filename与文件名比较后使用 PowerShell 脚本更正时间戳
【发布时间】:2018-12-09 21:11:42
【问题描述】:

我有一堆 .jpg 文件保存在不同的文件夹中,文件名上有错误的时间戳(延迟 1 小时),我想根据创建时间更正它。这样做的目的是获得一张 CSV 表,其中包含所有已更正的文件名及其完整路径。

我现在正在尝试编写一个 PowerShell 脚本,该脚本可以遍历所有文件夹,提取创建时间并将其替换为带有错误时间戳的文件名。下面是一个小例子:

带有错误时间戳的原始文件名:

文件名、创建日期、修改日期 20180524010500530_FR785101.jpg, 2018-05-24 00:05:00, 2018-05-24 00:05:34

正确的输出是:

文件名、创建日期、修改日期 20180524000500530_FR785101.jpg, 2018-05-24 00:05:00, 2018-05-24 00:05:34

我已经开始记录自己使用CreationTime 命令,但我仍然无法弄清楚如何提取创建时间并将其替换为文件名时间戳。另外,我不知道如何使脚本遍历包含图像文件的所有文件夹和子文件夹,最终将所有内容导出到 CSV 表中。

Get-ChildItem -Path "c:/path/to/files/" -Recurse -Include @("*.jpg") |
    Rename-Item -NewName {
        $_.Name -replace "IMG", ($_.CreationTime.ToString("yyyyMMdd"))
    }

更新:

我想要得到的最终.csv 输出如下所示:

File path, date time, name
path_of_file, Timestamp, Name
C:_users_mind_volume, 20180524000500530, FR785101

【问题讨论】:

  • "IMG" -> '^\d{8}'。将文件名中的前 8 位数字替换为创建日期。
  • @AnsgarWiechers 谢谢你的回答,但你能说得更具体点吗,我不太明白你的方法。

标签: powershell csv filenames


【解决方案1】:

你会寻找这样的东西来用正确的日期/时间重命名文件。

#Rename file directly to correct format.
Get-ChildItem -Filter '*.jpg' -Recurse | ForEach-Object {
    $NewTimestamp = $_.CreationTime.ToString('yyyyMMddHHmmss')
    Rename-Item -LiteralPath $_.FullName -NewName ($_.BaseName -replace '.*(_.*)',($NewTimestamp+'$1'+$_.Extension)) -WhatIf
}

这只会将它们导出到您桌面上的 csv 文件中。

#Export details to CSV
Get-ChildItem -Filter '*.jpg' -Recurse | Select FullName,CreationTime,LastWriteTime | Export-Csv -Path "~\Desktop\Images.csv" -NoTypeInformation

【讨论】:

  • 感谢您的回答,但您能告诉我如何使它遍历所有文件夹和子文件夹并给我每个文件的完整路径,我已经用确切的内容更新了问题我想要在 .csv 表上的输出
  • 更改名称 -> Select 部分中的 FullName 将为您提供所有文件的完整路径,Get-ChildItem 中的 -Recurse 已经贯穿所有子文件夹。
  • 酷,这看起来不错,但它只是用创建日期替换了整个文件名,它不仅仅是替换了前 8 个数字,是否可以添加一些更正的东西?
  • @WadeBlackmore 我针对您发布的其中一个文件名运行了这个,它对我来说很好用。你运行它的文件名是什么?
  • @WadeBlackmore 为什么您要用_ 替换它们?您是否希望将整个路径转换为文件名?你可能想问一个新的问题来说明你的理想最终结果,而不是问个别问题。
【解决方案2】:

以下解决方案:

  • 将脚本块直接传递给 -NewName 以计算新文件名(也用于您的问题),这比使用 ForEach-Object 调用其脚本更有效(也更简洁)在每次迭代中块调用Rename-Item

  • 使用 -PassThru 输出重命名的文件,从而启用到 Export-Csv 的管道,以便重命名文件并在单个管道中创建 CSV 文件。

  • 使用 calculated properties 来转换和重命名输出 CSV 文件的相关属性。

Get-ChildItem -Path "c:/path/to/files" -File -Recurse *.jpg | 
  Rename-Item -WhatIf -PassThru -NewName { 
     '{0}_{1}' -f $_.CreationTime.ToString('yyyyMMddHHmmssfff'),
                  ($_.Name -split '_')[1] 
    } | 
        Select-Object @{ n='path_of_file'; e={ $_.FullName -replace '\\', '_' } }, 
                      @{ n='Timestamp'; e={ ($_.BaseName -split '_')[0] } }, 
                      @{ n='Name'; e={ ($_.BaseName -split '_')[1] } } |
            Export-Csv -NoTypeInformation .\out.csv

注意-WhatIf 通用参数,它仅预览重命名操作,允许您验证新名称是否按预期构造。
删除 -WhatIf 以执行实际重命名。

【讨论】:

  • 这个解决方案对我不起作用,幸运的是我在运行脚本之前做了一个备份,因为它破坏了我的数据
  • @WadeBlackmore:关于元注释,在我们深入挖掘之前:我很遗憾听到它不起作用。但是,进行备份不应该是 运气 的问题:虽然这里的回答者(希望)提供他们自己测试过的解决方案(我有),但责任始终在 你 不要盲目地运行具有潜在破坏性的代码:要么使用示例文件,要么 - 始终 - 拥有可以恢复的备份。另外,如果不说以何种方式就说解决方案对您不起作用,对我和您都没有帮助:您仍然没有解决方案,我不知道如何解决我的答案。
  • 我已经更正了代码中的一个问题:更新的时间戳字符串最后缺少 3 位数字(小数秒)。除此之外,我认为没有问题,假设您的输入文件都遵循<timestamp-to-replace>_<part-to-preserve>.jpg 名称模式。
  • 我还添加了-WhatIf,以便默认情况下仅预览重命名操作 - 请参阅我的更新。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多