
Tengo problemas para obtener un valor de cadena de una matriz para insertarlo en la expresión regular en la -match
condición que Where-Object
se 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-Object
funció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 $ordArr
to sustituido en el comando.
Dependiendo de la combinación de llaves y marcas, devuelve nada o todo. Además, si debo ingresar manualmente 001
desde $ordArr
la 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-ChildItem
for la misma ubicación dentro de un bucle for
o 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)
}