Как можно проверить Get-ChildItem на отсутствие результатов (нулевые файлы)?

Я здесь в тупике из-за того, что кажется простой проблемой; так извините за всякую тупоголовость здесь.

У меня есть сценарий, который очищает несуществующие файлы резервных копий. После определения файлов я перебираю и распечатываю то, что сбрасывается. Моя проблема возникает при попытке предоставить обратную связь / тестирование, когда нет несуществующих файлов. Сценарий выглядит так ...

$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 “$File” 
      Remove-Item $File | out-null
   } 
}

При проверке отсутствия файлов условие отсутствия файлов не выполняется. Как лучше всего проверить $Files на отсутствие результатов?


person EBarr    schedule 28.07.2011    source источник


Ответы (5)


Попробуйте обернуть @(..). Он всегда создает массив:

$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 {
  ..
}
person stej    schedule 28.07.2011
comment
Это отличный трюк для необычной обработки / интерпретации массивов PowerShell. Спасибо! - person Eric Nicholson; 28.07.2011
comment
Увеличено, так как это, на мой взгляд, правильный (и простой) способ обработки массивов, которые могут иметь значение NULL или где следующий конвейер не сработает, если он имеет значение NULL. - person CosmosKey; 29.07.2011

Когда файлов нет, $ Files равно $ null, поэтому EBGreen предлагает вам протестировать против $ null. Кроме того, $ Files.Count полезен только тогда, когда результатом является коллекция файлов. Если результатом является скаляр (один объект), у него не будет свойства count, и сравнение не удастся.

Совет по производительности: когда вам нужно найти только один тип расширения, используйте параметр -Filter (вместо -Include), поскольку он фильтрует на уровне поставщика.

person Shay Levy    schedule 28.07.2011
comment
+1 для подсказки фильтра, но я упростил свой пример, и фильтр, похоже, не работает для нескольких расширений (* .bak и * .tran), как это делает include :-( - person EBarr; 29.07.2011
comment
Я сомневаюсь в этом ответе, поскольку if ($Files=$null) не возвращает истину, а if (!$Files) возвращает. - person Marc; 26.09.2016
comment
Извините, похоже, вы можете протестировать if ($Files -eq $null) или if (!$Files), но по какой-то причине if ($Files = $null) нет. - person Marc; 26.09.2016

Переменная оценивается как выражение с нулевым значением, когда отсканированная папка пуста. Вы можете использовать:

if (!$Files) {
# ...
}
person Emiliano Poggi    schedule 28.07.2011
comment
вы имеете в виду, если (! $ Files) {/ здесь нет файлов /}? - person EBarr; 28.07.2011
comment
Работает красиво и намного аккуратнее, чем утвержденный ответ. Спасибо. - person Juliusz; 18.08.2015
comment
Спасибо за вашу признательность. - person Emiliano Poggi; 19.08.2015

Попробуйте также проверить $ files -eq $ null.

person EBGreen    schedule 28.07.2011

Указание типа [bool] перед командой get-childitem вернет True, если что-то найдено, или false, если ничего не найдено. Это то, что делает ответ Эмилиано, но без отрицательного требования. Вы можете заставить работать и то, и другое, но я предпочитаю [bool] с некоторыми из более сложных условных операторов, чтобы было легче следовать.

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

Используется в операторе If

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