Lendo arquivos
Esta aula ensina a ler arquivos no PowerShell usando o cmdlet Get-Content, abordando a leitura completa com -Raw, a leitura linha a linha, e a importância do encoding para garantir a correta interpretação dos caracteres. Inclui exemplos práticos, exercícios com respostas e referências oficiais.
Ler arquivos é uma das tarefas mais comuns em automação e administração de sistemas. No PowerShell, o cmdlet Get-Content é a ferramenta principal para essa finalidade, oferecendo flexibilidade para ler desde arquivos pequenos até logs gigantescos, com opções de controle de encoding e processamento linha a linha.
Nesta aula, vamos explorar a fundo o Get-Content, suas variações, como usar o parâmetro -Raw para leitura completa, como processar arquivos linha a linha de forma eficiente e como lidar com diferentes codificações de texto, essenciais para evitar erros de exibição ou processamento.
Get-Content
O cmdlet Get-Content é o equivalente PowerShell do comando cat do Linux, mas com muito mais recursos. Ele lê o conteúdo de um arquivo e o envia para o pipeline, permitindo que você manipule o texto diretamente. Por padrão, ele retorna um array de strings, onde cada elemento corresponde a uma linha do arquivo.
Vejamos um exemplo básico. Suponha que temos um arquivo chamado exemplo.txt com o seguinte conteúdo:
Get-Content -Path C:\Temp\exemplo.txtIsso exibirá todas as linhas no console. O resultado é um array, então você pode armazená-lo em uma variável e acessar linhas específicas:
$linhas = Get-Content -Path C:\Temp\exemplo.txt
$linhas[0] # primeira linha
$linhas[-1] # última linhaAlém de -Path, você pode usar -LiteralPath quando o caminho contém caracteres curinga que não devem ser interpretados. O parâmetro -TotalCount permite ler apenas as primeiras N linhas, útil para inspecionar arquivos grandes sem carregar tudo na memória.
-Raw
O parâmetro -Raw altera o comportamento padrão: em vez de retornar um array de linhas, ele retorna o conteúdo completo do arquivo como uma única string, preservando as quebras de linha. Isso é útil quando você precisa tratar o arquivo como um bloco único, por exemplo, para fazer uma substituição global ou para passar o conteúdo para outro comando que espera uma string.
Exemplo:
$conteudo = Get-Content -Path C:\Temp\exemplo.txt -Raw
$conteudo -replace 'antigo', 'novo'Com -Raw, a variável $conteudo contém todo o texto, incluindo as quebras de linha. Sem -Raw, o conteúdo seria um array de strings e o operador -replace funcionaria em cada linha separadamente, o que pode ser menos intuitivo para substituições que envolvem múltiplas linhas.
Outra vantagem é que -Raw é mais rápido para arquivos grandes, pois lê tudo de uma vez, enquanto o modo padrão precisa dividir em linhas. No entanto, para arquivos muito grandes, isso pode consumir muita memória, então é importante avaliar o contexto.
Lendo linha a linha
Processar arquivos linha a linha é essencial quando o arquivo é muito grande para caber na memória ou quando você deseja aplicar uma lógica de filtragem ou transformação em cada linha. O PowerShell oferece duas abordagens principais: usar o pipeline com ForEach-Object ou usar o loop foreach.
Com o pipeline, cada linha é enviada assim que é lida, permitindo processamento em streaming:
Get-Content -Path C:\Temp\log.txt | ForEach-Object {
if ($_ -match 'erro') {
Write-Host $_
}
}Essa abordagem é eficiente e idiomática no PowerShell. O mesmo pode ser feito com um loop tradicional, mas é menos eficiente porque carrega todas as linhas na memória antes de iterar:
$linhas = Get-Content -Path C:\Temp\log.txt
foreach ($linha in $linhas) {
if ($linha -match 'erro') {
Write-Host $linha
}
}Para arquivos muito grandes, a abordagem com pipeline é preferível, pois não armazena todas as linhas ao mesmo tempo. Outra alternativa é usar o método [System.IO.File]::ReadLines(), que retorna um enumerador que também processa linha a linha de forma eficiente.
Encoding
Encoding (ou codificação de caracteres) é um aspecto crítico ao ler arquivos. O PowerShell precisa saber como interpretar os bytes do arquivo para convertê-los em caracteres corretamente. Se o encoding especificado não corresponder ao real, você verá caracteres estranhos (como "�") ou erros de leitura.
O Get-Content possui o parâmetro -Encoding que permite especificar a codificação. Os valores mais comuns são: UTF8, UTF7, UTF32, ASCII, Unicode (UTF-16), BigEndianUnicode, Default (ANSI), e OEM. No PowerShell 7+, você também pode usar o nome completo do encoding, como utf-8 ou iso-8859-1.
Exemplo:
Get-Content -Path C:\Temp\arquivo.txt -Encoding UTF8Se você não especificar, o PowerShell usa o encoding padrão, que no Windows PowerShell 5.1 é Default (ANSI), enquanto no PowerShell 7+ é UTF8 sem BOM. Para evitar problemas, é recomendável sempre especificar o encoding ao ler arquivos, especialmente se você sabe qual foi usado na criação.
Para descobrir o encoding de um arquivo, você pode usar o comando Format-Hex ou analisar os primeiros bytes (BOM). Por exemplo, um arquivo UTF-8 com BOM começa com os bytes EF BB BF.
Referências
- Documentação oficial do Get-Content
- Entendendo encoding no PowerShell
- Classe Encoding no .NET
- Sobre codificação de caracteres no PowerShell
- Sobre pipelines no PowerShell
Exercícios
Crie um arquivo chamado
teste.txtcom três linhas: "Linha 1", "Linha 2", "Linha 3". UsandoGet-Content, leia o arquivo e exiba a segunda linha.✓ Resposta:$linhas = Get-Content -Path C:\Temp\teste.txt $linhas[1] # Linha 2Leia o arquivo
teste.txtusando-Rawe conte quantos caracteres ele possui (incluindo quebras de linha).✓ Resposta:$conteudo = Get-Content -Path C:\Temp\teste.txt -Raw $conteudo.LengthEscreva um script que leia um arquivo de log linha a linha e exiba apenas as linhas que contêm a palavra "erro". Use o pipeline com
ForEach-Object.✓ Resposta:Get-Content -Path C:\Temp\log.txt | ForEach-Object { if ($_ -match 'erro') { Write-Host $_ } }Leia um arquivo com codificação UTF-8 explicitamente e exiba seu conteúdo no console. Explique por que é importante especificar o encoding.
✓ Resposta:Get-Content -Path C:\Temp\arquivo.txt -Encoding UTF8Especificar o encoding garante que os caracteres sejam interpretados corretamente. Se o arquivo estiver em UTF-8 e você não especificar, o PowerShell pode usar um encoding diferente (como ANSI), resultando em caracteres corrompidos.
Use
Get-Contentcom-TotalCountpara ler apenas as duas primeiras linhas de um arquivo grande, sem carregar todo o arquivo na memória.✓ Resposta:Get-Content -Path C:\Temp\grande.log -TotalCount 2
Boas Práticas e Observações Finais
Ao trabalhar com leitura de arquivos, sempre considere o tamanho do arquivo e o uso de memória. Para arquivos grandes, prefira o pipeline ou [System.IO.File]::ReadLines() para evitar estouro de memória. Sempre especifique o encoding quando souber, ou detecte-o antes de ler. Além disso, use -LiteralPath se o caminho contiver caracteres como colchetes ou curingas que possam ser interpretados erroneamente.
Outra dica: para arquivos com linhas muito longas, o Get-Content pode ser lento; considere usar StreamReader para controle mais fino. No entanto, para a maioria dos cenários, Get-Content é suficiente e mais simples.
Por fim, lembre-se de que o PowerShell 7+ tem diferenças em relação ao Windows PowerShell 5.1, principalmente no encoding padrão. Teste seus scripts em ambos se precisar de compatibilidade.