2012-06-13 36 views
8

Bien, esto me está volviendo loco porque mi expresión regular está funcionando en Rubular, pero PowerShell no está funcionando como esperaba.¿Cómo funciona PowerShell regex con cadenas de varias líneas?

  1. Hice un Get-ChildItem en un directorio de red y luego dirigí la salida a un archivo txt.
  2. Fui a retirar la información de directorio del archivo de texto que aparece como la siguiente:

enter image description here

  1. Cuando uso PowerShell para tratar de escribir una expresión regular para eliminar la información del Directorio, me encuentro con algunos problemas.

Cuando uso:

$var = Get-Contnet "file path" 
$var -match "Directory.*" 

PowerShell agarra el texto que estoy buscando, pero que no ase el texto que empieza en una nueva línea, consigo:

Directory: \\Drive\Unit\Proposals\Names\Location\crazy folder path\even crazier folder path\unbelievable folder path\ 
Así

... cuando uso:

$var -match "Directory.*\n.*" 

me sale nada ...

Cuando pruebo esto en Rublar funciona bien, ¿qué me falta aquí? ¡Cualquier ayuda sería genial, gracias!

Respuesta

19

respuesta de Filburt es buena, y no se ve como expresiones regulares son la mejor herramienta a utilizar aquí. Sin embargo, te topaste con un problema que puede causar confusión nuevamente en el futuro. El problema aquí es que la variable que rellenó con Get-Content no es una cadena de varias líneas. Es una matriz de cadenas:

$var = Get-Content "file path" 
$var.GetType() # Shows 'Object[]' 

Cuando se ejecuta un partido de expresiones regulares contra $var, que coincide con el uno contra el objeto de la matriz (cada línea en el archivo) de forma individual. No puede coincidir más allá del final de una línea porque la siguiente línea es un nuevo objeto.

Una solución aquí es que para aplanar matriz de cadenas hacia abajo en una sola cadena como esta:

$var = (Get-Content "file path" | Out-String) 
$var.GetType() # Shows 'String' now 

En Powershell a veces puede ser difícil saber cuándo se está tratando con un único objeto String frente a una conjunto de cadenas. Si los envía a la consola, parecen idénticos. En esos casos, GetType() y Out-String pueden ser herramientas útiles.

Editar: A partir de PowerShell 3.0, el proveedor Filesystem incluye un interruptor para -RawGet-Content. Ese modificador indica Get-Content para leer el archivo de una sola vez sin dividirlo en fragmentos. Es significativamente más rápido que usar la solución Out-String, porque no pierde tiempo separando piezas solo para volver a unirlas.

+1

¡Gracias! Ciertamente estoy de acuerdo en que Filburt tuvo la idea correcta, pero quería entender lo que me estaba perdiendo. ¡Más apreciado! – Steve

6

¿Por qué no seleccionar las propiedades deseadas antes de canalizarlas a su archivo?

Get-ChildItem | Select-Object Mode, LastWriteTime, Length, Name | Out-File Result.txt 
+0

¡Bien, señor, eso es una locura! De hecho, pensé en eso después de pensar en esto un poco más, pero me gustaría entender por qué mi expresión regular no funciona, ya que creo que debería ser para futuras referencias. – Steve

1

Es posible que las líneas no terminen en \n. Creo que los caracteres de terminación de línea estándar en Windows son \r\n. Intenta volver a escribir tu expresión regular para que coincida con eso.

+0

Gracias por la respuesta. Usar $ var -match "Directorio. * \ R \ n. *" O cualquier combinación de \ r \ n no funcionó. – Steve

+0

¡Gracias! Estaba atormentando mis cerebros durante una hora hasta que vi tu publicación y la resolví. – Jonathan

Cuestiones relacionadas