【问题标题】:Powershell Delete all files apart from the latest file per dayPowershell 每天删除除最新文件外的所有文件
【发布时间】:2019-12-25 14:15:28
【问题描述】:

我有一个文件夹,里面有很多文件,每天有多个文件。

我想编写一些脚本,每天删除除最新文件之外的所有文件。

我见过很多删除超过 X 天的文件的脚本,但这略有不同,并且在昨天之前没有写过 powershell(我完全是 tsql),我真的不知道该怎么做。

我不是要求任何人为我编写代码,但也许描述实现这一点的方法会很好,我可以研究如何将其付诸实践。

所有文件都在一个目录中,没有子文件夹。有些文件我不想删除,我要删除的文件的文件名格式为constant_filename_prefix_YYYYMMDDHHMMSS.zip

powershell 是正确的工具吗?我是否应该改用 Python(我也不知道)Powershell 更方便,因为我们拥有的其他代码是用 PS 编写的。

【问题讨论】:

  • 你试过什么?什么没有按预期工作?这个网站主要关注帮助现有代码 ... [grin]
  • 这是一种“我什至不知道从哪里开始”的情况
  • 啊!好吧,看起来Theo 为您提供了一些可以正常工作的代码... [grin]
  • 我们还没有收到您的来信.. 我的回答解决了您的问题吗?如果是这样,请点击左侧的✓ 考虑accepting。这将帮助其他有类似问题的人更轻松地找到它。

标签: powershell delete-file


【解决方案1】:

PowerShell 为这类事情提供了易于使用的 cmdlet。

我的问题是您是否希望使用文件名中的日期,或者文件本身的实际 LastWriteTime 日期(如文件资源管理器中所示)。

以下两种处理方式。我已经放了很多代码 cmets 来帮助您了解图片。

如果您想根据文件的实际上次写入时间删除文件:

$sourceFolder = 'D:\test'                                             # put the path to the folder where your files are here
$filePrefix   = 'constant_filename_prefix'

Get-ChildItem -Path $sourceFolder -Filter "$filePrefix*.zip" -File |  # get files that start with the prefix and have the extension '.zip'
    Where-Object { $_.BaseName -match '_\d{14}$' } |                  # that end with an underscore followed by 14 digits
    Sort-Object -Property LastWriteTime -Descending |                 # sort on the LastWriteTime property
    Select-Object -Skip 1 |                                           # select them all except for the first (most recent) one
    Remove-Item -Force -WhatIf                                        # delete these files

如果您想根据文件名中的日期删除文件。
因为您使用的日期格式是可排序的,所以您可以安全地对文件 BaseName 的最后 14 位进行排序:

$sourceFolder = 'D:\test' 
$filePrefix   = 'constant_filename_prefix'

Get-ChildItem -Path $sourceFolder -Filter "$filePrefix*.zip" -File |                 # get files that start with the prefix and have the extension '.zip'
    Where-Object { $_.BaseName -match '_\d{14}$' } |                                 # that end with an underscore followed by 14 digits
    Sort-Object -Property @{Expression = {$_.BaseName.Substring(14)}} -Descending |  # sort on the last 14 digits descending
    Select-Object -Skip 1 |                                                          # select them all except for the first (most recent) one
    Remove-Item -Force -WhatIf                                                       # delete these files

在这两种选择中,您都会发现-WhatIf 的末尾有一个开关Remove-Item cmdlet。 Yhis 用于测试代码,实际上不会删除任何文件。相反,使用此开关,它会在控制台中写出会发生什么

一旦您对此输出感到满意,您可以删除或注释掉 -WhatIf 开关,让代码删除文件。


更新

据我所知,该文件夹中有几天的多个文件,您希望每天保留最新的文件,删除其他文件。

在这种情况下,我们必须创建文件的“日”组,并按日期对每个组进行排序并删除旧文件。
这就是Group-Object 的用武之地。

方法 1) 使用文件的 LastWriteTime 属性

$sourceFolder = 'D:\test'                                               # put the path to the folder where your files are here
$filePrefix   = 'constant_filename_prefix'

Get-ChildItem -Path $sourceFolder -Filter "$filePrefix*.zip" -File |    # get files that start with the prefix and have the extension '.zip'
    Where-Object { $_.BaseName -match '_\d{14}$' } |                    # that end with an underscore followed by 14 digits
    Group-Object -Property @{Expression = { $_.LastWriteTime.Date }} |  # create groups based on the date part without time part
        ForEach-Object {
            $_.Group | 
            Sort-Object -Property LastWriteTime -Descending |           # sort on the LastWriteTime property
            Select-Object -Skip 1 |                                     # select them all except for the first (most recent) one
            Remove-Item -Force -WhatIf                                  # delete these files
        }

方法 2) 使用取自文件名的日期:

$sourceFolder = 'D:\test'                                                                    # put the path to the folder where your files are here
$filePrefix   = 'constant_filename_prefix'

Get-ChildItem -Path $sourceFolder -Filter "$filePrefix*.zip" -File |                         # get files that start with the prefix and have the extension '.zip'
    Where-Object { $_.BaseName -match '_\d{14}$' } |                                         # that end with an underscore followed by 14 digits
    Group-Object -Property @{Expression = { ($_.BaseName -split '_')[-1].Substring(0,8)}} |  # create groups based on the date part without time part
        ForEach-Object {
            $_.Group | 
            Sort-Object -Property @{Expression = {$_.BaseName.Substring(14)}} -Descending |  # sort on the last 14 digits descending
            Select-Object -Skip 1 |                                                          # select them all except for the first (most recent) one
            Remove-Item -Force -WhatIf                                                       # delete these files
        }

【讨论】:

  • 这并不能完全达到我想要达到的效果 - 这将删除所有匹配模式的文件,除了最新的。我想做的是每天保持最新的文件。例如,如果我有今天的三个文件和昨天的两个文件,我需要保留今天的最新文件和昨天的最新文件,只剩下 2 个文件。这样做是只保留今天最新的,只留下一个文件。不过感谢您的帮助 - 这个每天一个概念让我头疼。
  • @JamesLester 是的,我认为这就是您想要的。我现在在手机上,但明天会尝试给出另一个答案。您需要什么日期:文件 NAME 中的日期还是真正的 LastWriteTime?
  • @JamesLester 我已经更新了我的答案。它现在每天保留最新文件并删除旧文件。
猜你喜欢
  • 2016-09-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-03-03
  • 1970-01-01
  • 1970-01-01
  • 2021-01-19
相关资源
最近更新 更多