Как перебирать или перебирать папки, которые соответствуют определенному условию - PullRequest
0 голосов
/ 27 июня 2019

У меня есть каталог, который содержит папки, которые соответствуют датам (то есть датированные подпапки). Все они в одном формате yyyymmdd. В этом каталоге также есть другие папки с именами, которые являются текстовыми. То, что я пытаюсь сделать, - это написать скрипт, который будет принимать от пользователя, сколько дней назад он хотел бы видеть. Затем скрипт выполнит некоторые действия с каждой папкой. У меня возникли проблемы с поиском правильного получения списка всех папок.

Каталог будет выглядеть примерно так:

C:--/
    FOO--/
         --20190525
         --20190526
         --20190527
         --20190528
         --20190529
         --20190530
         --20190531
         --20190601
         --20190602
etc.

В настоящее время я использую цикл for, но проблема в том, что, когда наступает конец месяца, то есть 20190531, цикл продолжится до 20190532 вместо 20190601.

$lastday = (Get-Date).AddDays(-1).ToString("yyyyMMdd")
$lastdayint = [int]$lastday
$days = [Microsoft.VisualBasic.Interaction]::InputBox('How many days back do you want to process?')
if ($days.Length -eq 0) {
    Exit
}
$daysint = [int]$days
$firstday = (Get-Date).AddDays(-$daysint).ToString("yyyyMMdd")
$firstdayint = [int]$firstday

for ($i = $firstdayint; $i -le $lastdayint; $i++) {
    # Get our dated sub folder by looking through the root of FOO
    # and finding the folder that matches the condition
    $datedsub = (Get-ChildItem -Path "C:\FOO\*" | Where-Object { ($_.PSIsContainer) -and ($_.Name -eq [string]$i) } ).Name
    # If the path does not exist, both processes will fail, so exit out of the loop and move on to the next date
    if ( $( try { !(Test-Path -Path ("C:\FOO\$datedsub").Trim() -PathType Container) } catch { $false } ) ) {
        Continue
    }
}

Я застрял, пытаясь понять, как получить все папки с именами между двумя датами. Это было довольно легко сделать в сценариях CMD, так как все является строкой, а папки не имеют свойств. Но с Powershell это немного сложнее. Сценарий должен выполнить цикл по всем папкам в указанном диапазоне. Я почти уверен, что цикл foreach, вероятно, был бы моим лучшим выбором, но мне сложно понять, как его настроить.

Ответы [ 2 ]

1 голос
/ 27 июня 2019

Ваш код может быть упрощен в алгоритме:

[int]$days = [Microsoft.VisualBasic.Interaction]::InputBox('How many days back do you want to process?')
if ($days.Length -eq 0) {
    Exit
}

# will contain folders
$dirlist = @()

# note: includes today. To not include today, start $i at 1
for ($i = 0; $i -le $days; $i++) {
    $datestr = (Get-Date).AddDays(-$i).ToString("yyyyMMdd")
    $dir = Get-ChildItem -Path $datestr -Directory -ErrorAction SilentlyContinue
    if($null -ne $dir) {
        [void]$dirlist.Add($dir)
        # Or do work here. Otherwise you can use the outputted arraylist
    }
}

# prints folders to console
$dirlist

Выше:

  1. Запрашивает у пользователя количество дней назад
  2. Сохраняет столько раз, сколько циклов и дней
  3. Получает строку даты с использованием Today - $i
  4. Использует Get-ChildItem с -Path, чтобы найти элемент, -Directory, чтобы ограничить каталоги, и -ErrorAction SilentlyContinue, чтобы подавить ошибки (если он не существует, он вернет $null)
  5. Добавляет к ArrayList, если нет $null
1 голос
/ 27 июня 2019

Вместо преобразования строки в целое число и ее приращения вы должны использовать AddDays() для циклического отображения фактических дат:

$days = [Microsoft.VisualBasic.Interaction]::InputBox('How many days back do you want to process?')
if ($days.Length -eq 0) {
    Exit
}
$startDate = (Get-Date).AddDays(-$days)
$endDate = (Get-Date).AddDays(-1)

for($currentDate = $startDate; $currentDate -le $endDate; $currentDate.AddDays(1)) {
    $dateString = $currentDate.ToString('yyyyMMdd')
    if ( -not( Test-Path "C:\FOO\$dateString" -PathType Container ) ) {
        continue
    }
    # do work here
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...