如何根据重复的 .jpeg 文件(具有相同的 .BaseName)在过去 24 小时内是否发生更改来删除目录中的所有 .webp 文件?

How do I delete all .webp files in a directory based on if the duplicate .jpeg file (with the same .BaseName) has changed in the last 24 hours?

所以,我有一个网站的图片目录。有些图片带有 .jpeg 扩展名和 .webp 扩展名。我想编写一个 PowerShell 脚本来查找在过去 24 小时内更改的所有现有 .jpeg 文件,然后找到相应的 .webp 文件并删除 .webp 文件。

我试过这个来获取所有可以删除的 .webp 文件,但它似乎不起作用:

$images = Get-ChildItem -Path $dir\*.jpg, $dir\*.webp | 
Group-Object { $_.BaseName } |
    Where-Object {($_.CreationTime -gt (Get-Date).AddDays(-1)) -or ($_.Group.Extension -notcontains '.jpg')} | 
        ForEach-Object Group

我觉得这个更简单:

获取截至昨天最后修改的 jpg 文件的基本名称列表,接下来获取同一目录中扩展名为 .webp 的文件列表,这些文件的基本名称与 jpg 基本名称之一匹配,然后删除这些。

$dir     = 'D:\Test'
$refdate = (Get-Date).AddDays(-1).Date
$jpegs   = (Get-ChildItem -Path $dir -Filter '*.jpg' -File | Where-Object { $_.LastWriteTime -gt $refdate }).BaseName
Get-ChildItem -Path $dir -Filter '*.webp' -File | Where-Object { $jpegs -contains $_.BaseName } | Remove-Item -WhatIf

一旦您对正确的文件被删除感到满意,请移除安全 -WhatIf 开关并再次 运行。

shows you an alternative approach; if you want to stick with the Group-Object方法:

$webpFilesToDelete = 
  Get-ChildItem -Path $dir\*.jpg, $dir\*.webp | 
    Group-Object BaseName | Where-Object Count -eq 2 |
      ForEach-Object {
        # Test the creation date of the *.jpg file.
        if ($_.Group[0].CreationTime -gt (Get-Date).AddDays(-1)) {
          $_.Group[1] # Output the corresponding *.webp file
        }
      }
  • 请注意,在您自己的尝试中,使用了 .CreationTime,但请注意文件是否有机会在 之后再次更新创建,这是你关心的时间戳,你应该使用 .LastWriteTime.

  • 该命令依赖于 Group-Object 按排序标准对它创建的组的元素进行排序的事实,在本例中,由于按 分组string 属性 - 表示词法排序,其中 .jpg 个文件列在 .webp 个文件之前。

  • 因此,对于具有 2 个元素 (Where-Object Count -eq 2) 的组,意味着对于给定的基本名称,.jpg.webp 文件都存在, $_.Group[0] 指的是 .jpg 文件,$_.Group[1] 指的是 .webp 文件。


至于你试过的

  • $_.CreationTime 产生 $null,因为您命令中的 $_ 指的是手边的 group-information 对象(Microsoft.PowerShell.Commands.GroupInfo 的一个实例),由 Group-Object 输出,并且此类型没有 属性.

  • 此外,由于您使用的是 Where-Object,您只是在 过滤 个组,因此任何通过过滤器测试的组都是按原样传递,然后 ForEach-Object Group 输出组中的 both 个文件。

感谢您的帮助和澄清!我最初认为我需要 .LastWriteTime,但我需要 .CreationTime。这满足您的需求。这是结果:

$refdate = (Get-Date).AddDays(-1).Date
$jpegs   = (Get-ChildItem -Path $dir -Filter '*.jpg' -File | Where-Object { $_.CreationTime -gt $refdate }).BaseName
$webp = Get-ChildItem -Path $dir -Filter '*.webp' -File | Where-Object { $jpegs -contains $_.BaseName }