需要 Windows 批处理命令单线器按名称删除文件夹,而不是按 date.time 使用 powershell(如果适用)
Posted
技术标签:
【中文标题】需要 Windows 批处理命令单线器按名称删除文件夹,而不是按 date.time 使用 powershell(如果适用)【英文标题】:Need windows batch command one-liner to remove folders by name, not by date.time using powershell if applicable 【发布时间】:2021-11-20 07:02:05 【问题描述】:需要有关命令的帮助,如单线、powershell 以删除文件夹 我正在尝试找到一种优雅的方法来按反映日期的文件夹名称删除文件夹,但我不能依赖文件/文件夹日期元数据属性。
这是我要解决的问题:
我有一个文件夹,其中每天都有存档的通话录音,录音系统创建文件夹并用通话录音填充它们,每天的文件夹命名为MM_dd_yyyy
。
我需要删除除最后 7 个文件夹之外的所有文件夹。但是,我不能依赖文件上的创建/修改日期。仅使用 powershell 会容易得多。因此,不幸的是,我必须通过针对我需要以相同格式保留的文件夹的日期测试文件名来删除文件夹(MM_dd_yyyy)
。
我可以使用以下 Windows 命令行获取根据前 6 天保留的文件夹名称列表:
c:\>powershell $d0=(Get-Date).ToString('MM-dd-yyyy'); $d1=(Get-Date).AddDays(-1).ToString('MM-dd-yyyy'); $d2=(Get-Date).AddDays(-2).ToString('MM-dd-yyyy'); $d3=(Get-Date).AddDays(-3).ToString('MM-dd-yyyy'); $d4=(Get-Date).AddDays(-4).ToString('MM-dd-yyyy'); $d5=(Get-Date).AddDays(-5).ToString('MM-dd-yyyy'); $d6=(Get-Date).AddDays(-6).ToString('MM-dd-yyyy'); $d0; $d1; $d2; $d3; $d4; $d5; $d6
注意:由于公司和域强制执行的安全限制,我需要将其保存在单行命令中,并且不能使用 PS1 power shell 脚本
这会生成要保留的文件夹名称,如下所示(在 2021 年 11 月 20 日运行以保留过去 7 天)。
11_20_2021
11_19_2021
11_18_2021
11_17_2021
11_16_2021
11_15_2021
11_14_2021
其目的是删除任何文件夹名称,例如 11_13_2021、11_12_2021... 等。
我可以在 Windows bat 文件中运行嵌套的 FOR 循环来尝试将其组合在一起,但我正在尝试找到一个更简单、可读和优雅的单行代码,它可以让我执行以下操作:
电源外壳$d=(Get-Date).AddDays(-7).ToString('MM-dd-yyyy')
;然后是一些神奇的 powershell 东西来删除任何与要保留的文件夹不匹配的文件夹。
如果我有办法将文件夹名称 (MM_dd_yyyy)
提供给 (get-date).AddDays(-6)
powershell 命令并让它返回布尔值是或否,那将更接近我正在寻找的东西。
我一直在阅读,你在管和拔头发,但到目前为止我正在学习,但主要是把它弄得一团糟。欢迎任何想法。
我可能在处理这一切时都错了。约束是:
给定命名格式为MM_dd_yyyy
的文件夹列表,我需要删除/删除所有不在最后一周内的文件夹。
我无法运行 powershell 脚本 .ps1
我可以使用 for 循环等运行 windows bat 或 cmd 文件
我不能依赖文件日期/时间元属性的文件夹,文件夹中的某些数据可能具有不符合文件夹名称的创建/写入/修改日期。我必须依靠文件夹名称(MM_dd_yyyy)
来删除文件夹。
已更新分辨率:
powershell "($f=Get-ChildItem -Path 'D:\PosConvSav' -Filter '*_*_*' -Directory | Where-Object $_.Name -match '\d2_\d2_\d4' | sort-object -desc)[14..($_.count)] | remove-item -recurse"
【问题讨论】:
为什么一个衬里比两个或多个衬里或脚本更安全? 为什么你不能运行 powershell 脚本,但显然你可以运行一个调用 PowerShell 的 bat? 我正在使用的系统的所有者不允许我使用任何 PS1 或 vbs。我可以,但我会冒险。通常,如果我可以将其拉到单线中,即使它调用 powershell 或 wmic,我也可以侥幸逃脱。这更像是一种文化限制,而不是一种强制执行的限制。当我对 powershell 变得更加了解和胜任时,我将能够更好地保护我的工具的使用。 【参考方案1】:用于此的 PowerShell 代码是:
Get-ChildItem -Path 'RootPath\Where\The\Folders\To\Delete\Are\Found' -Filter '*_*_*' -Directory |
Where-Object $_.Name -match '\d2_\d2_\d4' | # filter some more using regex -match
Sort-Object [datetime]::ParseExact($_.Name, 'MM_dd_yyyy', $null) | # sort by date
Select-Object -SkipLast 7 | # skip the newest 7 folders
Remove-Item -Recurse -Force # remove the rest
为了安全起见,请将-WhatIf
添加到最后的Remove-Item
命令中。通过这样做,代码实际上并没有删除任何内容,而是在控制台中显示 将 删除的内容。如果您认为这是正确的,则删除 -WhatIf
以实际删除这些文件夹。
正如Olaf 已经评论的那样,不要认为使用单行代码是最好的,因为您最终会得到不再可读且极难发现错误的代码。 多行代码没有任何惩罚,事实上这是要走的路!
【讨论】:
Sort-Object 需要 -Descending 参数来保留最新的文件夹。 @nimizen 啊,是的,我太傻了.. 要么降序排序,要么使用-SkipLast
。现已修复
感谢您的帮助。根据您的意见,我学到了一些有用的东西,最终得到了我刚刚更新到帖子描述末尾的单行字。以上是关于需要 Windows 批处理命令单线器按名称删除文件夹,而不是按 date.time 使用 powershell(如果适用)的主要内容,如果未能解决你的问题,请参考以下文章