【问题标题】:Repeat foreach loop after all iteration completed in Powershell在 Powershell 中完成所有迭代后重复 foreach 循环
【发布时间】:2019-12-30 21:23:20
【问题描述】:

在 foreach 循环中的所有迭代完成后,这里的任何人都可以帮助我如何从头开始重复代码。下面的代码将在文件中获取所有具有“qwerty”模式的文件,在 foreach 循环中提供列表,并在每个文件上显示文件名和最后 10 行,如果在某些情况下没有新的/更新的文件,则终止代码时间

$today=(Get-date).Date

$FILES=Get-ChildItem -Path C:\Test\ | `
    Where-Object {$_.LastWriteTime -ge $today} | `
    Select-String -pattern "qwerty" | `
    Select-Object FileName -Unique

foreach ($i in $FILES) {
   Write-host $i -foregroundcolor red

   Get-content -Path \\XXXXXX\$i -tail 10
   Start-Sleep 1

} 

【问题讨论】:

  • [1] 你的问题是什么? [grin] [2] 请修正您的代码格式。您用于创建帖子的页面有一个指向格式说明的链接。

标签: powershell


【解决方案1】:

你可以用这个:

For ($r = 0; $r -eq NumberOfTimesYouWantToRepeat; $r++) {

  $today=(Get-date).Date

  $FILES=Get-ChildItem -Path C:\Test\ | `
    Where-Object {$_.LastWriteTime -ge $today} | `
    Select-String -pattern "qwerty" | `
    Select-Object FileName -Unique

  foreach ($i in $FILES) {
   Write-host $i -foregroundcolor red

   Get-content -Path \\XXXXXX\$i -tail 10
   Start-Sleep 1

  } 
}

PS:将 TheNumberOfTimesToRepeat 替换为您要重复的次数。

【讨论】:

  • 请考虑更改外部for 循环的$i 控制变量,因为它与循环体内的另一个$i 变量重合。
【解决方案2】:

如果我正确理解了这个问题,您想测试某个文件夹中包含某个字符串的文件。对于这些文件中的每一个,都应显示最后 10 行。

第一个困难来自您想在循环中执行此操作并测试新文件或更新文件。
这意味着您需要跟踪您已经测试过的文件,并且只显示新的或更新的文件。下面的代码为此使用了 Hashtable $alreadyChecked,因此我们可以测试文件是新文件还是更新文件。

如果在特定时间内没有找到新的或更新的文件,代码应该结束。为此,我使用了另外两个变量:$endTime$checkTime
$checkTime 每次迭代都会更新,使其成为当前时间
$endTime 只有在找到文件时才会更新.

$today          = (Get-Date).Date
$sourceFolder   = 'D:\Test'

$alreadyChecked = @{}   # a Hashtable to keep track of files already checked
$maxMinutes     = 5     # the max time in minutes to perform the loop when no new files or updates are added
$endTime        = (Get-Date).AddMinutes($maxMinutes)

do {
    $checkTime = Get-Date

    $files = Get-ChildItem -Path $sourceFolder -File |
        # only files created today and that have not been checked already
        Where-Object {$_.LastWriteTime -ge $today -and 
                      (!$alreadyChecked.ContainsKey($_.FullName) -or 
                        $alreadyChecked[$_.FullName].LastWriteTime -ne $_.LastWriteTime) } | 
        ForEach-Object {
            $filetime = $_.LastWriteTime  
            $_ | Select-String -Pattern "qwerty" -SimpleMatch |    # -SimpleMatch if you don't use a Regex match
            Select-Object Path, FileName, @{Name = 'LastWriteTime'; Expression = { $filetime }} 
    }

    if ($files) {
        foreach ($item in $files) {
           Write-Host $item.Filename -ForegroundColor Red
           Write-Host (Get-content -Path $item.Path -Tail 10)
           Write-Host
           # update the Hashtable to keep track of files already done
           $alreadyChecked[$item.Path] = $item | Select-Object FileName, LastWriteTime
           Start-Sleep 1
        }
        # files were found, so update the time to check for no updates/new files
        $endTime = (Get-Date).AddMinutes($maxMinutes)
    }
    # exit the loop if no new or updated files have been found during $maxMinutes time
} while ($checkTime -le $endTime)

对于演示,如果未找到新文件或更新文件,我将使用 5 分钟等待循环到期,但您可以根据需要进行更改。

【讨论】:

    猜你喜欢
    • 2016-07-28
    • 2015-03-20
    • 1970-01-01
    • 1970-01-01
    • 2016-08-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多