【问题标题】:How to iterate or loop through folders that match a certain condition如何迭代或循环匹配特定条件的文件夹
【发布时间】:2019-06-27 06:13:26
【问题描述】:

我的目录包含与日期相对应的文件夹(即日期子文件夹)。它们都采用相同的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 循环可能是我最好的选择,但我无法弄清楚如何设置它。

【问题讨论】:

    标签: windows powershell


    【解决方案1】:

    您的代码可以在算法上进行简化:

    [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. 如果不是$null,则添加到ArrayList

    【讨论】:

    • 这主要是我所做的。该阵列绝对是我正在寻找的。最大的变化是$dirlist += $dir,因为提前声明数组设置了它的大小。我还颠倒了数组,使它从最早的日期开始,然后foreach ($dateddir in $dirlist) { ....etc. } 循环遍历数组并对其进行处理。
    【解决方案2】:

    您应该使用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
    }
    

    【讨论】:

    • 这不起作用。 $currentdate.AddDays(1) 似乎并没有真正增加这一天。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-06-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多