PowerShell: almacenar todo el contenido del archivo de texto en variable

118

Me gustaría usar PowerShell para almacenar todo el contenido de un archivo de texto (incluida la línea en blanco al final que puede existir o no) en una variable. También me gustaría saber el número total de líneas en el archivo de texto. ¿Cuál es la forma más eficaz de hacer esto?

Mella
fuente

Respuestas:

122

Para obtener todo el contenido de un archivo:

$content = [IO.File]::ReadAllText(".\test.txt")

Número de líneas:

([IO.File]::ReadAllLines(".\test.txt")).length

o

(gc .\test.ps1).length

Una especie de truco para incluir una línea vacía al final:

[io.file]::ReadAllText(".\desktop\git-python\test.ps1").split("`n").count
manojlds
fuente
1
¡Gracias! $content = [IO.File]::ReadAllText(".\test.txt")parece hacer lo mismo que $content = (gc ".\test.txt" | out-string). Como el segundo de los dos es más corto, eso es lo que prefiero. Desafortunadamente, ninguno de los métodos que proporcionó para calcular el número total de líneas tiene en cuenta las líneas en blanco finales. ¿Alguna otra idea?
Nick
@Nick En .Net (y windows), se \r\ncontará cualquier línea con .
manojlds
Estaba experimentando un poco y se me ocurrió lo mismo que tu respuesta actualizada, pero no habría llegado allí sin tu ayuda, ¡así que muchas gracias!
Nick
¿Hay alguna forma de combinar esto de forma transparente Invoke-WebRequest?
Kareem
189

En una nota al margen, en PowerShell 3.0 puede usar el Get-Contentcmdlet con el nuevo modificador Raw:

$text = Get-Content .\file.txt -Raw 
Shay Levy
fuente
3
Esta debería ser la respuesta aceptada. Por cierto, estoy bastante seguro de que Get-Content funcionó incluso en versiones anteriores.
MatteoSp
10
@MatteoSp lo Get-Contenthizo, pero no fue hasta la 3.0 que lo consiguió -Raw. Sin eso, se almacena como una matriz de líneas.
jpmc26
Esta debería ser absolutamente la respuesta aceptada. No ayuda que la documentación diga que el -Rawparámetro no está implementado por nada nativo.
Richard Szalay
Gracias, esto fue de gran ayuda en este momento.
DAhrens
24

Powershell 2.0:

(ver explicación detallada aquí)

$text = Get-Content $filePath | Out-String

El IO.File.ReadAllTextno funcionó para mí con una ruta relativa, se busca el archivo en %USERPROFILE%\$filePathlugar del directorio actual (cuando se ejecuta desde PowerShell ISE al menos):

$text = [IO.File]::ReadAllText($filePath)

Powershell 3+:

$text = Get-Content $filePath -Raw
Kapé
fuente
Para usar rutas familiares, resuélvalas primero, por ejemplo:[IO.File]::ReadAllText((Resolve-Path $filePath))
mvanle
13

Un enfoque más para leer un archivo que me gusta se conoce de diversas maneras como notación variable o sintaxis variable e implica simplemente encerrar una especificación de archivo entre llaves precedidas por un signo de dólar, a saber:

$content = ${C:file.txt}

Esta notación se puede utilizar como valor L o valor R ; por lo tanto, podría escribir fácilmente en un archivo con algo como esto:

 ${D:\path\to\file.txt} = $content

Otro uso útil es que puede modificar un archivo en su lugar sin un archivo temporal y sin subexpresiones, por ejemplo:

${C:file.txt} = ${C:file.txt} | select -skip 1

¡Al principio me fascinó esta notación porque era muy difícil averiguar algo sobre ella! Incluso la especificación PowerShell 2.0 lo menciona solo una vez y muestra solo una línea usándolo, pero sin explicación ni detalles de uso. Posteriormente, encontré esta entrada de blog sobre variables de PowerShell que brinda algunas buenas perspectivas.

Una nota final sobre el uso de esto: debe usar una designación de unidad, es decir, ${drive:filespec}como he hecho en todos los ejemplos anteriores. Sin la unidad (por ejemplo ${file.txt}) no funciona. No hay restricciones en la especificación del archivo en esa unidad: puede ser absoluta o relativa.

Michael Sorens
fuente
Nunca he conseguido que esto funcione a menos que ponga una barra invertida después del nombre de la unidad.
Charles Anderson
@CharlesAnderson: No está claro a cuál de los tres ejemplos se refiere, o quizás a todos ellos ... sin embargo, acabo de confirmar que los 3 funcionan con una ruta relativa (es decir, sin barra invertida) en PowerShell V3. Además, en el momento de mi respuesta, estaba usando V2, por lo que quizás haya algo más que cause un problema en su entorno.
Michael Sorens
Me refiero a ejemplos como $ {C: file.txt}, que tengo que escribir como $ {C: \ file.txt}. Sí, supongo que es algo sobre mi entorno, pero no tengo idea de qué.
Charles Anderson
Cuando se usa como valor L, usa la codificación predeterminada del sistema. Intenté configurar $ OutputEncoding sin ningún efecto. Cuando se usa como valor R, produce una matriz de cadena [].
robert4
Parece que solo puede usar un nombre de ruta literal; no puede usar una variable o algo como una expresión Join-Path dentro de esto. Lo cual es molesto, porque cuando se canaliza a través de ConvertTo-Json, hay una gran diferencia en comparación con Get-Content (y el resultado $ {...} es lo que esperaba. No estoy seguro de si esto es lo mismo como Get-Content | Sin embargo, Out-String
Cameron Kerr
2

Get-Content toma datos y los vuelca en una matriz, línea por línea. Suponiendo que no haya otros requisitos especiales que los que enumeró, ¿podría guardar su contenido en una variable?

$file = Get-Content c:\file\whatever.txt

Ejecutar solo $filedevolverá el contenido completo. Entonces puede hacer $file.Count(porque las matrices ya tienen un método de recuento incorporado) para obtener el número total de líneas.

¡Espero que esto ayude! No soy un genio de las secuencias de comandos, pero esto me pareció más fácil que muchas de las cosas anteriores.

Jerry T.
fuente