PowerShell: Armazene todo o conteúdo do arquivo de texto na variável

118

Eu gostaria de usar o PowerShell para armazenar todo o conteúdo de um arquivo de texto (incluindo a linha em branco à direita que pode ou não existir) em uma variável. Também gostaria de saber o número total de linhas no arquivo de texto. Qual é a maneira mais eficiente de fazer isso?

usuario
fonte

Respostas:

122

Para obter todo o conteúdo de um arquivo:

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

Número de linhas:

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

ou

(gc .\test.ps1).length

Tipo de hackeamento para incluir uma linha vazia à direita:

[io.file]::ReadAllText(".\desktop\git-python\test.ps1").split("`n").count
manojlds
fonte
1
Obrigado! $content = [IO.File]::ReadAllText(".\test.txt")parece fazer a mesma coisa que $content = (gc ".\test.txt" | out-string). Como o segundo dos dois é mais curto, é o que eu prefiro. Infelizmente, nenhum dos métodos fornecidos para calcular o número total de linhas leva em consideração as linhas em branco à direita. Alguma outra ideia?
Nick
@Nick Em .Net (e windows), qualquer linha com \r\nserá contada.
manojlds
Eu estava fazendo alguns experimentos e encontrei a mesma coisa que sua resposta atualizada, mas não teria chegado lá sem sua ajuda, então muito obrigado!
Nick
Existe uma maneira de combinar isso com transparência Invoke-WebRequest?
Kareem,
189

Em uma observação lateral, no PowerShell 3.0, você pode usar o Get-Contentcmdlet com a nova opção Raw:

$text = Get-Content .\file.txt -Raw 
Shay Levy
fonte
3
Esta deve ser a resposta aceita. A propósito, tenho certeza de que Get-Content funcionou mesmo nas versões anteriores.
MatteoSp
10
O @MatteoSp Get-Contentsim, mas não foi até o 3.0 que ele apareceu -Raw. Sem isso, ele é armazenado como uma matriz de linhas.
jpmc26
Esta deve ser absolutamente a resposta aceita. Não ajuda que a documentação diga que o -Rawparâmetro não é implementado por nada nativo.
Richard Szalay
Obrigado, esta foi uma grande ajuda agora mesmo.
DAhrens
24

Powershell 2.0:

(veja a explicação detalhada aqui)

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

O IO.File.ReadAllTextnão funcionou para mim com um caminho relativo, ele procura o arquivo em %USERPROFILE%\$filePathvez do diretório atual (ao executar do Powershell ISE, pelo menos):

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

Powershell 3+:

$text = Get-Content $filePath -Raw
Kapé
fonte
Para usar caminhos parentes, resolva-o primeiro, por exemplo:[IO.File]::ReadAllText((Resolve-Path $filePath))
mvanle
13

Outra abordagem para ler um arquivo de que gosto é referida de várias maneiras como notação de variável ou sintaxe de variável e envolve simplesmente colocar uma especificação de arquivo entre chaves precedidas por um cifrão, a saber:

$content = ${C:file.txt}

Esta notação pode ser usada como um valor L ou um valor R ; assim, você poderia facilmente gravar em um arquivo com algo assim:

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

Outro uso útil é que você pode modificar um arquivo local sem um arquivo temporário e sem subexpressões, por exemplo:

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

Fiquei fascinado por essa notação inicialmente porque era muito difícil descobrir qualquer coisa sobre ela! Até mesmo a especificação do PowerShell 2.0 menciona apenas uma vez, mostrando apenas uma linha de uso - mas sem nenhuma explicação ou detalhes de uso. Posteriormente, encontrei esta entrada de blog sobre variáveis ​​do PowerShell que oferece alguns bons insights.

Uma observação final sobre como usar isso: você deve usar uma designação de unidade, ou seja, ${drive:filespec}como fiz em todos os exemplos acima. Sem a unidade (por exemplo ${file.txt}) não funciona. Sem restrições na especificação do arquivo nessa unidade: pode ser absoluto ou relativo.

Michael Sorens
fonte
Nunca fiz isso funcionar, a menos que coloque uma barra invertida após o nome da unidade.
Charles Anderson
@CharlesAnderson: Não está claro a qual dos três exemplos você está se referindo, ou talvez todos eles ... no entanto, acabei de confirmar que todos os três funcionam com um caminho relativo (ou seja, sem barra invertida) no PowerShell V3. Além disso, no momento da minha resposta, eu estava usando a V2, então talvez haja algo mais causando um problema em seu ambiente.
Michael Sorens
Eu quis dizer exemplos como $ {C: file.txt}, que tenho que escrever como $ {C: \ file.txt}. Sim, presumo que seja algo sobre meu ambiente, mas não tenho ideia do que seja.
Charles Anderson
Ao usar como valor L, ele usa a codificação padrão do sistema. Tentei definir $ OutputEncoding sem efeito. Ao usar como valor R, ele produz uma matriz string [].
robert4
Parece que você só pode usar um nome de caminho literal; você não pode usar uma variável ou algo como uma expressão Join-Path dentro dela. O que é irritante, porque quando canalizado por meio de ConvertTo-Json, há um mundo de diferença em comparação com Get-Content (e o resultado $ {...} é o que eu esperava. Não tenho certeza se é o mesmo como Get-Content | Out-String embora
Cameron Kerr
2

Get-Content captura dados e os despeja em uma matriz, linha por linha. Supondo que não haja outros requisitos especiais além dos listados, você poderia simplesmente salvar seu conteúdo em uma variável?

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

Executar apenas $fileretornará o conteúdo completo. Então você pode simplesmente fazer $file.Count(porque os arrays já têm um método de contagem embutido) para obter o número total de linhas.

Espero que isto ajude! Não sou um gênio de scripts, mas isso parecia mais fácil para mim do que muitas das coisas acima.

Jerry T.
fonte