Comparteix a través de


about_Foreach

Descripción breve

Describe un comando de lenguaje que puede usar para recorrer todos los elementos de una colección de elementos.

Descripción larga

La instrucción foreach es una construcción de lenguaje para recorrer en iteración un conjunto de valores de una colección.

El tipo de colección más sencillo y típico que se va a recorrer es una matriz. Dentro de un bucle foreach, es habitual ejecutar uno o varios comandos en cada elemento de una matriz.

Syntax

A continuación se muestra la sintaxis foreach:

foreach ($<item> in $<collection>){<statement list>}

La parte de la instrucción foreach entre paréntesis representa una variable y una colección que se va a iterar. PowerShell crea la variable $<item> automáticamente cuando se ejecuta el bucle foreach. Al principio de cada iteración, foreach establece la variable de elemento en el siguiente valor de la colección. El bloque {<statement list>} contiene los comandos que se van a ejecutar para cada iteración.

Ejemplos

Por ejemplo, el bucle foreach del ejemplo siguiente muestra los valores de la matriz $letterArray.

$letterArray = 'a','b','c','d'
foreach ($letter in $letterArray)
{
  Write-Host $letter
}

En este ejemplo, el $letterArray contiene los valores de cadena a, b, cy d. La primera vez que se ejecuta la instrucción foreach, establece la variable $letter igual al primer elemento de $letterArray (a). A continuación, usa Write-Host para mostrar el valor. La próxima vez a través del bucle , $letter se establece en b. El patrón se repite para cada elemento de la matriz.

También puede usar instrucciones foreach con cmdlets que devuelven una colección de elementos. En el ejemplo siguiente, la instrucción foreach recorre la lista de elementos devueltos por el cmdlet Get-ChildItem.

foreach ($file in Get-ChildItem)
{
  Write-Host $file
}

Puede refinar el ejemplo mediante una instrucción if para limitar los resultados que se devuelven. En el ejemplo siguiente, la instrucción if limita los resultados a los archivos que tienen más de 100 kilobytes (KB):

foreach ($file in Get-ChildItem)
{
  if ($file.Length -gt 100KB)
  {
    Write-Host $file
  }
}

En este ejemplo, el bucle foreach usa una propiedad de la variable $file para realizar una operación de comparación ($file.Length -gt 100KB). La variable $file tiene todas las propiedades del objeto devuelto por el Get-ChildItem.

En el ejemplo siguiente, el script muestra la longitud y la hora de último acceso dentro de la lista de instrucciones:

foreach ($file in Get-ChildItem)
{
  if ($file.Length -gt 100KB)
  {
    Write-Host $file
    Write-Host $file.Length
    Write-Host $file.LastAccessTime
  }
}

También puede usar variables desde fuera de un bucle foreach. En el ejemplo siguiente se cuentan los archivos de más de 100 KB de tamaño:

$i = 0
foreach ($file in Get-ChildItem) {
  if ($file.Length -gt 100KB) {
    Write-Host $file 'file size:' ($file.Length / 1024).ToString('F0') KB
    $i = $i + 1
  }
}

if ($i -ne 0) {
  Write-Host
  Write-Host $i ' file(s) over 100KB in the current directory.'
}
else {
  Write-Host 'No files greater than 100KB in the current directory.'
}

En el ejemplo anterior, $i comienza con un valor de 0 fuera del bucle. A continuación, $i se incrementa dentro del bucle para cada archivo que sea mayor que 100 KB. Cuando se cierra el bucle, una instrucción if evalúa el valor de $i para mostrar un recuento de archivos de más de 100 KB.

En el ejemplo anterior también se muestra cómo dar formato a los resultados de longitud de archivo:

($file.Length / 1024).ToString('F0')

El valor se divide en 1024 para mostrar los resultados en kilobytes en lugar de bytes y, a continuación, se da formato al valor resultante mediante el especificador de formato de punto fijo para quitar los valores decimales del resultado. El 0 hace que el especificador de formato no muestre posiciones decimales.

La función siguiente analiza los scripts de PowerShell y los módulos de script y devuelve la ubicación de las funciones contenidas en . En el ejemplo se muestra cómo usar el MoveNext método y la Current propiedad de la $foreach variable dentro de un foreach bloque de instrucciones.

Para obtener más información, vea Using Enumerators.

function Get-FunctionPosition {
  [CmdletBinding()]
  [OutputType('FunctionPosition')]
  param(
    [Parameter(Position = 0, Mandatory,
      ValueFromPipeline, ValueFromPipelineByPropertyName)]
    [ValidateNotNullOrEmpty()]
    [Alias('PSPath')]
    [System.String[]]
    $Path
  )

  process {
    try {
      $filesToProcess = if ($_ -is [System.IO.FileSystemInfo]) {
        $_
      } else {
        Get-Item -Path $Path
      }
      $parser = [System.Management.Automation.Language.Parser]
      foreach ($item in $filesToProcess) {
        if ($item.PSIsContainer -or
            $item.Extension -notin @('.ps1', '.psm1')) {
          continue
        }
        $tokens = $errors = $null
        $ast = $parser::ParseFile($item.FullName, ([ref]$tokens),
          ([ref]$errors))
        if ($errors) {
          $msg = "File '{0}' has {1} parser errors." -f $item.FullName,
            $errors.Count
          Write-Warning $msg
        }
        :tokenLoop foreach ($token in $tokens) {
          if ($token.Kind -ne 'Function') {
            continue
          }
          $position = $token.Extent.StartLineNumber
          do {
            if (-not $foreach.MoveNext()) {
              break tokenLoop
            }
            $token = $foreach.Current
          } until ($token.Kind -in @('Generic', 'Identifier'))
          $functionPosition = [pscustomobject]@{
            Name       = $token.Text
            LineNumber = $position
            Path       = $item.FullName
          }
          $addMemberSplat = @{
              InputObject = $functionPosition
              TypeName = 'FunctionPosition'
              PassThru = $true
          }
          Add-Member @addMemberSplat
        }
      }
    }
    catch {
      throw
    }
  }
}

Consulte también