PowerShell: Cómo sustituir el valor de una matriz en una expresión regular dentro de Where-Object -MATCH

PowerShell: Cómo sustituir el valor de una matriz en una expresión regular dentro de Where-Object -MATCH

Tengo problemas para obtener un valor de cadena de una matriz para insertarlo en la expresión regular en la -matchcondición que Where-Objectse muestra a continuación.

$ordArr = @("001", "005", "002", "007")

for ($i = 0; $i -le $ordArr.Length) {
  get-childitem -file -recurse |
    where-object {$_.BaseName -match "^$ordArr[$i].*$"} |
      ForEach-Object {echo $_}

  $i = ($i + 2)
}

Si debo ingresar $ordArr[$i]solo (es decir, llamarlo fuera de la presencia de la Where-Objectfunción, devuelve los valores de cadena esperados.

yo también lo he probado

  • ... -match "^${ordArr[$i]}.*$ ... "
  • ... -match "^${ordArr[$[tick mark]{i[tick mark]}]}.*$ ... "

y otros misceláneos. combinaciones utilizando mercados de ticks y llaves. Sin embargo, no puedo obtener el valor de la cadena de $ordArrto sustituido en el comando.

Dependiendo de la combinación de llaves y marcas, devuelve nada o todo. Además, si debo ingresar manualmente 001desde $ordArrla expresión regular, ... -match "^001.*$" ...devolverá los archivos que espero.

Entonces, ¿cómo puedo insertar un valor de una matriz en la condición de expresión regular dentro Where-Object ... -match ...?

¡Gracias!

Respuesta1

Su patrón de expresiones regulares no interpola la cadena como desea.

"^$ordArr[$i].*$"}resultados en^001 005 002 007[0].*$

Tienes que usar eloperador de subexpresión $()si desea utilizar expresiones como cálculos ( $int1 + $int2), acceso a miembros ( $something.Path), acceso a índices ( $array[1]), etc. dentro de otra expresión como una cadena.

En tu caso tienes que poner tu $ordArr[$i]en una subexpresión:

"^$($ordArr[$i]).*$"

Ver:MSFT: operador de subexpresión $( )

Además, debes evitar utilizar Get-ChildItemfor la misma ubicación dentro de un bucle foro foreach. En su ejemplo, llama a Get-ChildItem de forma recursiva 4 veces para los mismos elementos.

Mi sugerencia

Mi sugerencia es definir un patrón de expresiones regulares combinado para tener uno solo en lugar de realizar varios bucles sobre una matriz para crear un patrón. Esto es mucho más rápido que otros enfoques.

$ordArr = @('001', '005', '002', '007')

# build a combined regex pattern 
#   this time we don't need a subexpression operator, since we don't access any member or index from $_
$regexPattern = ($ordArr | ForEach-Object { "^$_.*$" }) -join '|'

Get-ChildItem -File -Recurse | Where-Object {
    $_.BaseName -match  $regexPattern 

    # as alternative and to avoid saving anything to the automatic variable $matches (-> better performance)
    # but not idiomatic Powershell:
    # [regex]::IsMatch($_.BaseName, $regexPattern)
}

información relacionada