Estoy trabajando con algunos archivos de texto de varios gigabytes y quiero hacer un procesamiento de transmisión en ellos usando PowerShell. Es algo simple, simplemente analizar cada línea y extraer algunos datos, luego almacenarlos en una base de datos.
Desafortunadamente, get-content | %{ whatever($_) }
parece mantener todo el conjunto de líneas en esta etapa de la tubería en la memoria. También es sorprendentemente lento, y lleva mucho tiempo leerlo todo.
Entonces mi pregunta tiene dos partes:
- ¿Cómo puedo hacer que procese la secuencia línea por línea y no mantenga todo en búfer en la memoria? Me gustaría evitar utilizar varios gigas de RAM para este propósito.
- ¿Cómo puedo hacer que funcione más rápido? La iteración de PowerShell sobre un
get-content
parece ser 100 veces más lenta que un script de C #.
Espero que haya algo tonto que estoy haciendo aquí, como perder un -LineBufferSize
parámetro o algo ...
fuente
get-content
, establezca -ReadCount en 512. Tenga en cuenta que en este punto, $ _ en Foreach será una matriz de cadenas.Get-Content
a una variable, ya que cargará todo el archivo en la memoria. De forma predeterminada, en una pipleline,Get-Content
procesa el archivo una línea a la vez. Siempre que no esté acumulando los resultados o utilizando un cmdlet que se acumula internamente (como Sort-Object y Group-Object), el impacto de la memoria no debería ser tan malo. Foreach-Object (%) es una forma segura de procesar cada línea, una a la vez.get-content | % -End { }
, se queja porque no ha proporcionado un bloque de proceso. Por lo tanto, no puede usar -End por defecto, debe usar -Process por defecto. Y trate de1..5 | % -process { } -end { 'q' }
ver que el bloque final solo ocurre una vez, lo habitualgc | % { $_ }
no funcionaría si el bloque de secuencia de comandos estuviera predeterminado en -End ...