如果文件名称重复但日期不同,请删除最早的日期

时间:2017-02-01 15:42:23

标签: powershell

我们进行了数据库备份,其名称如下:

[dbname]_[date&time].bak

这些备份是通过内部软件自动完成的,没有人愿意接触,我们现在只想为每个数据库进行1次备份。

所以在一个文件夹中可以有例如;

testdatabase_2017_01_20.bak
testdatabase_2017_02_01.bak

testdatabase01_2017_01_21.bak
testdatabase01_2017_01_23.bak

我想要做的是使用PowerShell脚本识别数据库名称中的匹配,然后继续删除最旧的。

到目前为止,我已经提出了以下内容

$regex =[regex] '\d{4}_\d{2}_\d{2}'  
$match = $regex.Match($File)

if ($match.Success)
{
    $startingIndex = $match.Index
    $newString = $File.ToString()

    $dublicates = ,$newString.Substring(0,$startingIndex) + $dublicates
}

$dublicates的输出将在我们的示例中

testdatabase_
testdatabase_
testdatabase01_
testdatabase01_

我没有坚持的是怎么说,因为$dublicates中有匹配找到哪一个最旧并删除了实际文件。

2 个答案:

答案 0 :(得分:2)

这是Group-object的标准用例。一般程序如下:

  • 收集输入数据。
  • 按主要区别特征对输入数据进行分组。
  • 选择包含多个元素的所有组。
  • 按次要区别特征对每个组进行排序,然后选择所需的元素。
  • 调用所选元素的操作。

在您的特定情况下:

  • 枚举您的文件。
  • 按部分名称对文件进行分组。
  • 选择包含多个文件的所有组。
  • 按日期对每个组进行排序,然后选择最旧的文件。
  • 删除所选文件。
Get-ChildItem 'C:\backup\folder' -Filter '*.bak' |
  Group-Object { $_.BaseName.Split('_', 2)[0] } |
  Where-Object { $_.Count -gt 1 } |
  ForEach-Object { $_.Group | Sort-Object LastWriteTime | Select-Object -First 1 } |
  Remove-Item -Force

如果您不能(或者不想)使用文件的最后修改时间,您可以从文件名中提取日期并将其用作排序属性:

... | Sort-Object { $_.BaseName.Split('_', 2)[1] } | ...

答案 1 :(得分:1)

试试这个

Get-ChildItem "c:\temp\" -file | where Name -match "._(\d{4})_(\d{2})_(\d{2})" |
    select fullname, @{N="DtFile";E={[DateTime]$_.BaseName.substring($_.BaseName.length -10).replace("_", "-")}},  
            @{N="FileWithoutDate";E={$_.BaseName.substring(0, $_.BaseName.length -11)}} | 
                group FileWithoutDate | 
                        where Count -GT 1 |
                            %{ $_.Group | sort DtFile -Descending | select -first 1} | %{Remove-Item $_.FullName}