当多次使用通配符删除与特定文件名模式匹配的文件时,PowerShell 的性能会下降

当多次使用通配符删除与特定文件名模式匹配的文件时,PowerShell 的性能会下降

正如我在 Q-title 中提到的,我已经构建了相当完善的功能来完全清除历史记录(不保留任何难看的垃圾或残留物)。

但似乎由于通配符(*)多次出现,它根本无法执行,并且历史文件仍然存在。

这是我整理的代码(它被添加到$profile文件中,因此可以从系统中的任何位置访问),它相当简单并且肯定可以工作,因为 Powershell 开发人员使命令变得大多相似并且符合 Bash/Batch 脚本的对应要求:

if (Get-Command -Verb Invoke -Noun Remove-Alias) {
    Remove-Alias history
} else {
    If (Test-Path Alias:history) {Remove-Item Alias:history}
    If (Test-Path Alias:history) {Remove-Item Alias:history}
}

function history {
    param (
        # Clears history
        [Parameter()]
        [Alias("c")]
        [Switch]
        $Clear
    )

    if ($Clear){
        Clear-History
        [Microsoft.PowerShell.PSConsoleReadLine]::ClearHistory()
        rm -fo -r $ENV:APPDATA\Microsoft\Windows\PowerShell\*history*
        del -fo -r $ENV:APPDATA\Microsoft\Windows\PowerShell\*history*
        return
    }

    Get-History
}

但是当我在任何地方使用这个Aliasthro'时history -c,它都不会删除ConsoleHost_history.txt现在的$ENV:APPDATA\Microsoft\Windows\PowerShell\PSReadLine,这确实是不受欢迎和出乎意料的,有人可以帮助指出错误的地方吗(是不是因为与 bash 不同,不接受多个星号作为通配符?)并提出最少的更改建议?

笔记:Windows 10 64 位和 Powershell >= 5.0

答案1

不是,这是因为 PowerShell 对rm通配符的解释喜欢bash 会这样做 – 非递归的。如果您尝试在 bash 中执行相同操作,您会注意到PowerShell/*history*仅匹配PowerShell/Command_history.txt但从不匹配PowerShell/PSReadLine/Command_history.txt,并且您需要**(bash 的“globstar”选项)才能匹配后者。

只有 PowerShelldir是这里的特殊情况,它会在提供的路径的子目录中查找,*history*就像您提供了通配符一样-Filter(结果类似于它在 Cmd.exe 中的工作方式)。例如,它们做同样的事情,但是仅有的dir

dir -r $ENV:APPDATA\Microsoft\Windows\PowerShell -filter *history*
dir -r $ENV:APPDATA\Microsoft\Windows\PowerShell\*history*

如果没有给出参数,许多 cmdlet 会隐式地对“输入对象”进行操作,因此您可以直接将 PowerShelldir导入rm

dir -r $ENV:APPDATA\Microsoft\Windows\PowerShell\*history* | rm -whatif

当然,将子目录包含在通配符中会更简单PSReadLine,因为无论如何它始终是路径的一部分:

rm $ENV:APPDATA\Microsoft\Windows\PowerShell\PSReadLine\*history*

相关内容