【问题标题】:How do I make a 3-way comparison for a file-count?如何对文件计数进行 3 向比较?
【发布时间】:2015-07-14 05:03:11
【问题描述】:

我有一个脚本,它将根据时间间隔计算文件夹中的文件。它将写入文件夹中的文件数量并对其进行颜色编码。我的问题是我需要它返回 3 个值:绿色、黄色或红色。

如果文件少于 10 个,则将前景色输出为绿色。 如果大于 10 但小于 20,则输出前景色为黄色。 如果大于 21,则输出为红色。

如何设置中间值的上限,以便红色可以自己显示?

$Counter = Read-Host "Enter Update Interval"
$timeout = new-timespan -Minutes 1
$sw = [diagnostics.stopwatch]::StartNew()

Write-Host "Outbound Script"
$Counter
while ($sw.elapsed -lt $timeout){
  if ((Get-ChildItem \\server\folder).count -le 12) {
    Write-Host (Get-ChildItem \\server\folder).count "Items in Outbound" -ForegroundColor Green
  } else {
    Write-Host (Get-ChildItem \\server\folder).count "Items in Outbound" -ForegroundColor Yellow
  }
  start-sleep -seconds $Counter
}

Write-Host "Times-Out"

我尝试为所有 Get-ChildItem 创建一个变量,但由于某种原因,如果我这样做,它只会计算一次。

【问题讨论】:

  • 显示您对变量所做的尝试?这里的问题是如何添加另一个 if 测试?

标签: powershell


【解决方案1】:

根据您的情况有多疯狂,在此处使用switch 将是有益的。另外,希望不要太过分,我们可以使用splatting 来实现,这样如果您的消息文本发生变化,您只需编辑一行。

$filecount = (Get-ChildItem \\server\folder).count
$color = @{}

switch($filecount){
    {$_ -le 10 }{$color.ForegroundColor = "Green"}
    {11..20 -contains $_}{$color.ForegroundColor = "Yellow"}
    {$_ -gt 20}{$color.ForegroundColor = "Red"}
}

Write-Host "$FileCount Items in Outbound" @color

11..20 -contains $_ 涵盖范围要求。如果$filecount 介于 10 和 21 之间,则该条件成立。更技术性的解释:11..20 使用范围运算符创建一个数字数组,我们使用-contains 来查看其中一个元素是否为$filecount。请注意这里的条件顺序。

【讨论】:

  • 我喜欢使用 splatting,但他们为什么要小心条件顺序呢? $filecount 只能匹配您在此处显示的内容的一个条件,所以顺序应该无关紧要吧?
  • @TheMadTechnician 是的,对于我在这种情况下所展示的内容。但是,如果 OP 采用此方法并做一些不同的事情,则可能需要使用 breaks。我只是想表明这些条件不是相互排斥的(
  • 公平地说,switch 中的条件绝对不是互斥的,除非明确设计为(例如在您的示例中)。顺便说一句,我建议尽可能在开关中使用Continue,因为Break 可能会产生不良影响,具体取决于它的使用位置。我记得读过一些奇怪的案例,比如在ForEach-Object 中嵌入switch 并使用Break 停止ForEach-Object 或类似的疯狂。
  • @TheMadTechnician .... 我总是在开关中休息并继续混淆。谢谢提醒。
【解决方案2】:
$Counter = Read-Host "Enter Update Interval"
$timeout = new-timespan -Minutes 1
$sw = [diagnostics.stopwatch]::StartNew()

Write-Host "Outbound Script"
$Counter
While ($sw.elapsed -lt $timeout){
    $FileCount = (Get-ChildItem \\server\folder).count

    If ($FileCount -le 10) {
        Write-Host "$FileCount Items in Outbound" -ForegroundColor Green
    } ElseIf ($FileCount -ge 11 -and $FileCount -le 20) {
        Write-Host "$FileCount Items in Outbound" -ForegroundColor Yellow
    } Else {
        Write-Host "$FileCount Items in Outbound" -ForegroundColor Red
    }

    Start-Sleep -seconds $Counter
}

Write-Host "Times-Out"

【讨论】:

  • 谢谢彼得。以后您可以通过单击底部的编辑链接来编辑帖子以修复这些小错误。
  • 对于单个角色来说,这并不容易……您必须至少更改 6 个 ;-)
  • 第二个if 不需要$FileCount -ge 11 -or。首先,这是完全错误的:你必须使用-and(否则它总是评估为$true),其次,它已经被第一个if覆盖了,不需要第二次检查。
  • 您对-or 开关的看法是正确的。我修好了它。但为了清楚起见,我留下了另一部分。你是对的,虽然它可以省略。
【解决方案3】:

添加 elseif 语句。

IF ((Get-ChildItem \\server\folder).count -le 12) {...}
ELSEIF ((Get-ChildItem \\server\folder).count -lt 20) {...}
ELSE {...}

【讨论】:

  • 我会避免重复相同的 cmdlet 调用。它不必要的冗余和低效。只需将其存储在变量中即可。
  • 另一个想法:虽然不太可能,但文件计数可能会在条件检查之间发生变化。
  • 非常感谢! elseif 和 -ge -and 命令一样感谢大家!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-08-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-07-06
相关资源
最近更新 更多