PowerShell查找文件夹,删除文件并保留最新的5个。

4
我们使用一种名为Revit的软件,文件保存格式为:filename.rvt。
每当用户编辑一个文件时,Revit会自行将旧文件保存在格式为 filename.xxxx.rvt 的文件中(其中xxx是一个数字)。
随着时间的推移,当文件被编辑数百次时,我们在文件服务器上有很多不必要的文件。
我正在编写一个脚本来实现以下操作:
- 查找并定位包含Revit备份文件的文件夹 - 删除所有旧的Revit备份文件,只保留最近修改的5个
我尝试了以下两种方法。
$searchpath = "e:\"
# Find a unique list of directories that contains a revit backup file (*.*.rvt)
$a = Get-ChildItem -Path $searchpath -Include *.*.rvt -Recurse | Select-object Directory -expandproperty FullName | Get-Unique -AsString

# For each folder that contains a single revit backup file (*.*.rvt)...
# - Sort by modified time
# - Select all except first 5
$a | Get-ChildItem -Include *.*.rvt | Sort-Object LastWriteTime -descending | select-object -skip 5 -property Directory,Name,CreationTime,LastWriteTime | Out-GridView -Title "Old Backups" -PassThru

这种方法的问题在于仅“跳过”了整个搜索结果中的前5个文件,而不是每个文件夹中的前5个文件。
接着我尝试使用循环来解决,但这样并没有解决问题。
$searchpath = "e:\"

# Find a unique list of directories that contains a revit backup file (*.*.rvt)
$a = Get-ChildItem -Path $searchpath -Include *.*.rvt -Recurse | Select Directory | Get-Unique -AsString 

# For each folder that contains a single revit backup file (*.*.rvt)...
# - Sort by modified time
# - Select all except first 5
$a | foreach {
 $b += Get-ChildItem -Path $_.Directory.FullName -Include *.*.rvt | Sort-Object LastWriteTime -descending | select-object -skip 5 -property Directory,Name,CreationTime,LastWriteTime
}

$b | Out-GridView -Title "Old Backups" -PassThru

有没有关于正确方法和出错原因的想法?
4个回答

3

试试这个:

get-childitem -file -recurse | group Directory | where Count -gt 5 | %{
    $_.Group | Sort LastWriteTime -descending | select -skip 5 Directory,Name,CreationTime,LastWriteTime 
} | Out-GridView -Title "Old Backups"

如果你想删除,你可以这样做(删除什么?)

gci -file -recurse | group Directory | where Count -gt 5 | %{
$_.Group | Sort LastWriteTime -descending | select -skip 5 | remove-item -WhatIf 
} 

1
尝试类似以下内容:

尝试以下代码:

$searchpath = "E:\"
$number = 5

$directories = Get-ChildItem -Path $searchpath -Include *.*.rvt -Recurse | Where-Object {$_.PsIsContainer}
foreach ($dir in $directories) 
{
    $files = Get-ChildItem -Path $dir.FullName | Where-Object {-not $_.PsIsContainer}
    if ($files.Count -gt $number) 
{
  $files | Sort-Object CreationTime | Select-Object -First ($files.Count - $number) | Remove-Item -Force
}
}

根据逻辑方法更改占位符。我只是给了你逻辑方法。

谢谢回复。第一个 Get-ChildItem 是在搜索文件夹名称而不是文件名。 - user3565039
是的,你只需要这个。原因是:你希望选择那些文件所在的文件夹,而不是所有文件夹。然后,在循环内完成必要的操作。 :) - Ranadip Dutta
我需要搜索文件名来定位文件夹,而不是文件夹名称。 - user3565039
那就开始吧。从where-object中删除文件夹条件并放入您的标准。 :) - Ranadip Dutta

1
你要做的关键是使用 Group-Object 命令。
在你的情况下,你想要创建的分组是包含同一文件夹中所有项目的组。这将会给你类似于以下的结果:

Grouped object

从那里,您可以对每个组执行操作,例如选择所有文件,跳过每个文件夹的前5个文件并删除其余文件。

看这个简单的极简主义示例:

$Path = 'C:\__TMP\1'
$Items = Get-ChildItem -Path "$path\*.rvt" -Recurse | Group-Object -Property PsparentPath

Foreach ($ItemsGroup in $Items) {
    $SortedFiles = $ItemsGroup.Group | sort LastWriteTime -Descending
    $SortedFiles | Select-Object -Skip 5 | % {Write-host "Deleting $($_.FullName)";  Remove-Item $_.FullName}
}

我认为给用户一个UI是明智的 - 因为我们正在删除文件... - user3565039
对于$Items中的每个$ItemsGroup { $SortedFiles = $ItemsGroup.Group | sort LastWriteTime -Descending $a += ($SortedFiles | Select-Object -Skip 5 -property Directory,Name,CreationTime,LastWriteTime) }$a | Out-GridView -Title "旧备份" -PassThru | Remove-Item -Force - user3565039
出现错误:Remove-Item: 找不到驱动器。名为“@{Directory=C”的驱动器不存在。 - user3565039
已解决:$a | Out-GridView -Title "旧备份" -PassThru | ForEach-Object { Remove-Item "$($.Directory)$($.Name)" -WhatIf } - user3565039

0
一个不需要先进行分组,而是单独处理每个目录的替代方案:
& { Get-Item $path; Get-ChildItem -Directory -Recurse $path } | # get all dirs.
  ForEach-Object {                            # for each dir.
    Get-ChildItem -File $_.FullName/*.*.rvt | # get backup files in dir.
      Sort-Object -Descending LastWriteTime | # sort by last-write time, newest first
        Select-Object -Skip 5 |               # skip the 5 newest
          Remove-Item -Force -WhatIf          # delete
  }

注意:上述命令中的-WhatIf常见参数预览操作。一旦确定操作符合您的要求,请删除-WhatIf


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接