Extrair apenas certas linhas de um arquivo texto. (Python/Powershell)
Overview
Se você já se viu perdido enquanto procurava por uma agulha no palheiro em um arquivo de log gigantesco, esse post é a luz no fim do túnel! Vou guiar você pelo processo de extração de linhas específicas utilizando Python e PowerShell, duas ferramentas poderosas para analisar e filtrar dados. Com exemplos práticos e direto ao ponto, espero que essa leitura transforme sua maneira de lidar com arquivos texto. Preparado para tornar sua vida infinitamente mais fácil? Vamos nessa!
A ideia deste post é demonstrar uma das formas de se extrair de um arquivo texto, apenas linhas que possuam determinada palavra-chave. Este tipo de abordagem é especialmente útil quando precisamos procurar um texto em um log muito grande. Vou mostrar como fazer isso em Python e o equivalente utilizando PowerShell.
Obvio que as soluções que vou apresentar não são soluções finais ou únicas, mas podem ajudar que estiver passando por este tipo de situação: Analisar toneladas de texto e tentar descobrir onde deu ruim.
Primeiro vamos definir alguns pontos em comum nas duas abordagens (Python e Powershell):
- Nome do arquivo que vai ser lido. (in_file = “big_logfile.txt”)
- O arquivo que vai receber as linhas extraídas. (out_file = “file_with_extractedlines.txt”)
- Qual texto queremos encontrar nas linhas do arquivo (search_for = “ERROR”)
- O número da linha que está sendo lida (line_num = 0)
- Quantidade de linhas encontradas (lines_found = 0)
Uma observação importante: Não vou adicionar rotinas de verificação se o texto está maiúsculo ou minusculo, mas você deve ter isso em mente.
Utilizando Python!
Primeiro, vamos declaras as variáveis que vamos precisar:
in_file = "big_logfile.txt"
out_file = "file_with_extractedlines.txt"
search_for = "ERROR"
line_num = 0
lines_found = 0
As três primeiras variáveis são as que estabelecemos no inicio deste post. As duas últimas (line_num e lines_found) são, respectivamente o número da linha que está sendo lida e a quantidade de linhas que possuem o texto procurado (search_for).
O próximo passo é abrir o arquivo de saída, o arquivo de log e fazer a interação pelas linhas.
with open(out_file, 'w') as out_f:
with open(in_file, "r") as in_f:
for line in in_f:
line_num += 1
if search_for in line:
lines_found += 1
print("Found '{}' in line {}...".format(search_for, line_num))
out_f.write(line)
print("Found {} lines...".format(lines_found))
Explicando (linha a linha) o que este script faz:
- Primeiro abrimos o arquivo de saída (referenciado na variável out_f), que vai armazenas as linhas que contém o texto que procuramos;
- Depois abrimos o arquivo de LOG (referenciado na variável in_f);
- A terceira linha é a declaração da iteração que faremos com o arquivo de log (in_f) para verificar linha a linha;
- Na quarta linha, incremento o valor de line_num, que guarda o número da linha que estamos lendo. Poderia utilizar o enumerate, mas imagino que isso poderia gerar perda de performance;
- Depois verificamos se o texto que queremos (search_for) existe na linha que estamos lendo (line). As linhas 6, 7 e 8 ocorrem apenas se o texto for encontrado na linha:
- Incremento o número de linhas que possuem o texto (lines_found);
- Mostro uma mensagem no console, falando que encontrei uma linha com o texto e qual o número dela (no arquivo original);
- Escrevo no arquivo de saída (out_f);
- No final de tudo, mostro uma mensagem falando a quantidade de linhas que encontrei.
Utilizando Powershell!
A abordagem que vamos utilizar no PowerShell é (basicamente) a mesma.
Primeiro, vamos declarar as variáveis que vamos utilizar:
$in_file = "big_logfile.txt"
$out_file = "file_with_extractedlines.txt"
$search_for = "ERROR"
$line_num = 0
$lines_found = 0
As variáveis são as mesmas e com os mesmos propósitos:
- $in_file: Arquivo contendo as linhas que serão examinadas;
- $out_file: Arquivo que receberá as linhas extraídas;
- $search_for: Texto que será procurado em cada linha;
- $line_num: Número da linha que está sendo examinada;
- $lines_found: Quantidade de linhas encontradas;
A “grande” diferença entre a abordagem com Python e a com o Powershell é a seguinte:
$log_lines = Get-Content $in_file # Var holding the lines of the log file.
O comando acima recupera o conteúdo do arquivo de log e o armazena na variável log_lines.
Agora, vamos para o processamento das linhas:
foreach ($line in $log_lines) {
$line_num++
if ($line.Contains($search_for)) {
$lines_found++
Write-Host "Text '$search_for' found in line $line_num..."
$line | out-file -FilePath $out_file -Append
}
}
Write-Host "Found $lines_found lines..."
Explicando (linha a linha) o que este script faz:
- Uma vez que já possuímos o conteúdo do arquivo, a primeira linha inicia uma iteração por cada linha do arquivo;
- Na segunda linha incrementamos o número da linha que está sendo lida;
- Depois verificamos se o texto que queremos (search_for) existe na linha que estamos lendo (line). As linhas 6, 7 e 8 ocorrem apenas se o texto for encontrado na linha:
- Incremento o número de linhas que possuem o texto (lines_found);
- Mostro uma mensagem no console, falando que encontrei uma linha com o texto e qual o número dela (no arquivo original);
- Escrevo no arquivo de saída (out_file);
- No final de tudo, mostro uma mensagem falando a quantidade de linhas que encontrei.
Observações sobre ambas abordagens
- A parte de contar as linhas encontradas, os prints e mostrar qual linha estamos lendo (obviamente) são opcionais e você pode remove-las sem problemas.
- Exemplo em Python (Github): https://github.com/brenordv/python-snippets/blob/master/extract-lines/extract_lines.py
- Exemplo em PowerShell (Github): https://github.com/brenordv/powershell-snippets/blob/master/extract-line/extract_lines.ps1
Espero ter ajudado.