【问题标题】:how to search files and display progress bar in powershell如何在powershell中搜索文件并显示进度条
【发布时间】:2017-11-14 23:42:52
【问题描述】:

我目前正在使用 Powershell 进行编码,我现在正在寻找一种在系统搜索文档时显示进度条的方法。我正在使用Get-ChildItem 而不是循环,因为它比循环快得多。我已经想出了如何使用Get-ChildItem cmdlet,但我需要帮助弄清楚如何在其中实现进度条。这是我正在使用的代码示例,因此更容易理解:

Set-Variable $Loading 0
Write-Progress -Activity "Collecting Files For Removal..." -CurrentOperation "Collecting User Files..." -PercentComplete $Loading
Get-ChildItem C:\Users\firea\ -Filter *.D11 -ErrorAction SilentlyContinue -Force

【问题讨论】:

  • Write-Progress 并不是真正设计用于测量像Get-ChildItem 这样的命令的运行时间。您更有可能将其用作完成的比较,例如,如果您有一组文件,并且您正在移动它们,您可以在 ForEach 循环中使用 Write-Progress 在每次复制后更新或那种性质的东西。
  • @TheIncorrigible1 好吧,我最近一直在尝试减少循环,因为它们比较复杂(我昨天刚开始使用 Powershell),而且我试图保持简单。不过,您确实有一点……一旦我得到更高级的东西,我可能会在不同的项目中尝试这种方法。您还有其他可行的想法吗?
  • 如何显示搜索的进度条?系统在完成之前不知道它的上限。 Get-ChildItem 是一个单独的 cmdlet,您不能在同一线程中运行任何其他内容,直到它完成为止,显示进度条是没有意义的。如果你想要一个进度条,系统需要事先获取数据,这意味着你必须先进行扫描。而且您将不得不使用您极力避免的“可怕”循环。
  • 根据 Rohin 的建议,您无法显示进度条,因为系统在完成之前不知道它必须查看的文件总数。除此之外,PowerShell 一次只做一件事,没有一些相当先进的技术,因此搜索硬盘驱动器并同时显示/更新进度条并不是一个简单的请求。如果您真的想了解如何操作,请查看this link。如果您是新手,请准备好让您的大脑融化一点。
  • 只是技术性问题,但我想帮助您了解您的术语以避免混淆。 Get-ChildItem 是 cmdlet,而不是脚本。当您编写一系列命令来完成一个或多个任务时,您会得到一个脚本。当提到循环时,它只是一个循环,而不是循环程序。程序意味着 PowerShell 外部的东西,例如 Word 或 Internet Explorer。

标签: windows file powershell get-childitem


【解决方案1】:

所以,听起来您想向用户显示一个显示 X% 已完成的进度条,但在您运行 Get-ChildItem 之前,您不知道总共有多少项,所以您不能真的告诉你有多接近完成。让我换一种说法。

假设你出去远足。您可以在网上快速搜索当地的小径,找到一条,然后出发!你知道小径从哪里开始,你知道它的尽头有一个玉米狗摊,你期待着取样。徒步旅行 12 分钟后,你的女朋友打电话给你,并要求你也给她带一条玉米狗回来!当然,没问题,当它到达她的时候它可能会很冷,但你可以做到这一点。然后她问需要多长时间,你意识到你不知道。你走了 12 分钟,但在你到达那个玉米狗摊之前,你不知道是再过 3 分钟还是 35 分钟,因为你不知道这条路有多长。

好的,同样的场景,但这次你会看到越过小径的高空滑索并先走。当然,您不知道小径的所有细节是什么,但您会很好地了解它有多长,并对小径有一个大致的了解。这次当你的女朋友打电话时,你可以告诉她大约 20 分钟,因为你大约 12 分钟进去,大约 4 分钟到看台,然后再过 16 分钟回到她所在的地方。

同样的想法也适用于您的脚本。为了给用户一个粗略的进度估计,您必须对您正在查看的内容有一个粗略的了解。您在搜索 1 个文件夹吗?好吧,确实没有什么好方法可以粗略估计一个文件夹,但是您需要一个进度条应该不会花那么长时间。现在,如果您正在搜索整个驱动​​器,您可以使用 Get-ChildItem-directory 参数,找出有多少文件夹,并根据您搜索的文件夹数量为用户提供进度。

例子:

#Get directory list, silently continue on errors in case script isn't run as an admin and there are system folders
$folders = Get-ChildItem C:\Users -Recurse -Directory -ErrorAction SilentlyContinue
#Loop through folders, checking each for files
$files = For($i = 0; $i -lt $folders.count; $i++)
{
    #Update progress bar for current folder
    Write-Progress -Activity "Collecting Files For Removal..." -CurrentOperation "Collecting User Files..." -PercentComplete (($i+1) / $folders.count * 100) -Status ("Folder {0} of {1}" -f ($i + 1), $folders.count)
    Get-ChildItem $folders[$i].FullName -Filter *.D11 -ea 4
}

此示例获取 C:\Users 文件夹下的所有文件夹。然后它遍历这些文件夹,检查每个文件夹是否有所需的文件。对于每个文件夹,它都会更新进度条。现在这将是一个粗略的估计,因为并非所有文件夹都有相同数量的文件,所以一些文件夹会比其他文件夹更快地完成,但它至少让用户对正在取得的进展有所了解。

【讨论】:

  • 我想我明白了——但请记住,我的自闭症让我的大脑处理事情的方式不同,其中一些让我有点困惑。如果您提供了一个我可以使用的脚本示例,我会更好地理解。不过,感谢您的尝试;我很感激人们至少在这里试图帮助我。如果你决定给出一个脚本,请尽量使脚本尽可能简单,因为循环脚本在 Powershell 中有点奇怪。 (因为这个原因,我比 Powershell 更喜欢 Python 风格)
猜你喜欢
  • 2011-07-01
  • 1970-01-01
  • 2019-01-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-01-26
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多