如何测试 Get-ChildItem 是否没有结果(零个文件)?

37

我在这里遇到了一个似乎很简单的问题,但却束手无策;对此感到非常抱歉。

我有一个清理废弃备份文件的脚本。在识别文件后,我循环遍历并打印出正在被删除的内容。我的问题是当没有废弃文件时如何提供反馈/测试。脚本看起来像这样...

$Files = Get-ChildItem $BackupPath_Root -include *.bak -recurse 
           | where {$_.CreationTime  -le $DelDate_Backup }  

if ( $Files -eq "" -or $Files.Count  -eq 0 ) {
    write-host "   no files to delete."    #<-- this doesn't print when no files
} else {
   foreach ($File in $Files) {
      write-host$FileRemove-Item $File | out-null
   } 
}

检查没有文件的 if 语句无法捕获没有文件的情况。测试 $Files 是否有结果的适当方法是什么?

5个回答

63

尝试用@(..)包裹起来。它总是创建一个数组:

$Files = @(Get-ChildItem $BackupPath_Root -include *.bak -recurse 
           | where {$_.CreationTime  -le $DelDate_Backup })
if ($Files.length -eq 0) {
  write-host "   no files to delete." 
} else {
  ..
}

2
这是一个非常棒的技巧,用于处理/解释奇怪的PowerShell数组。谢谢! - Eric Nicholson
我认为这是处理可能为空的数组或在其后的管道将失败的正确(且简单)方法。 - CosmosKey

17
当没有文件时,$Files等于$null,因此像EBGreen建议的那样,您应该针对$null进行测试。另外,当结果是文件集合时,$Files.Count才有用。如果结果是标量(一个对象),则它将没有计数属性并且比较失败。
性能提示:当您需要搜索一个扩展类型时,请使用-Filter参数(而不是-Include),因为它在提供程序级别上进行过滤。

1
+1 对于筛选器提示的赞同,但是我简化了我的示例,筛选器似乎不能像包含那样处理多个扩展名(*.bak 和 *.tran) :-( - EBarr
我必须对这个答案表示怀疑,因为 if ($Files=$null) 不会返回 true,但是 if (!$Files) 会。 - Marc
抱歉,显然你可以测试 if ($Files -eq $null)if (!$Files),但出于某种原因,不能使用 if ($Files = $null) - Marc

10

当扫描的文件夹为空时,该变量将评估为空值表达式。您可以使用以下方法:

if (!$Files) {
# ...
}

你指的是 if (!$Files) { /写没有文件在这里/ } 吗? - EBarr
1
运行得很好,比批准的答案更整洁。谢谢。 - Juliusz
感谢您的赞赏。 - Emiliano Poggi

4

也可以尝试测试 $files -eq $null。


2

在get-childitem命令前指定[bool]类型将返回True(如果找到任何内容)或False(如果未找到任何内容)。这就是Emiliano的答案所做的事情,但没有负面要求。你可以让两者都起作用,但我更喜欢在一些更复杂的条件语句中使用[bool],以使其更易于理解。

[bool](Get-ChildItem C:\foo.txt)

用于 If 语句中

if ([bool](Get-ChildItem C:\foo.txt)) {write-output "foo.txt exists"}

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