Tentando depurar um problema em um servidor e meu único arquivo de log é um arquivo de 20 GB (sem timestamps! Por que as pessoas usam System.out.println()
como log? Na produção ?!)
Usando grep, encontrei uma área do arquivo que gostaria de dar uma olhada na linha 347340107.
Além de fazer algo como
head -<$LINENUM + 10> filename | tail -20
... o que exigiria head
a leitura das primeiras 347 milhões de linhas do arquivo de log, existe um comando rápido e fácil que despejaria as linhas 347340100 - 347340200 (por exemplo) no console?
update Esqueci totalmente que o grep pode imprimir o contexto em torno de uma partida ... isso funciona bem. Obrigado!
Respostas:
com o GNU-grep você poderia dizer
fonte
Encontrei duas outras soluções, se você souber o número da linha, mas nada mais (não é possível grep):
Supondo que você precise das linhas 20 a 40,
ou
fonte
41q
instrua o sed a sair de linha41
.método 3 eficiente em arquivos grandes
maneira mais rápida de exibir linhas específicas
fonte
Não, não há, os arquivos não são endereçáveis por linha.
Não existe uma maneira constante de encontrar o início da linha n em um arquivo de texto. Você deve transmitir pelo arquivo e contar novas linhas.
Use a ferramenta mais simples / rápida para executar o trabalho. Para mim, usar
head
faz muito mais sentido do quegrep
, uma vez que o último é muito mais complicado. Não estou dizendo "grep
é lento", realmente não é, mas ficaria surpreso se for mais rápido do quehead
neste caso. Isso seria um bughead
, basicamente.fonte
A respeito:
Não testei, mas acho que funcionaria.
fonte
Eu prefiro apenas entrar
less
e:43210
para fazer o mesmoe coisas assim.
Ainda melhor: pressione vpara começar a editar (no vim, é claro!), Naquele local. Agora, observe que
vim
possui as mesmas ligações de teclas!fonte
Eu primeiro dividi o arquivo em alguns menores como este
e depois grep nos arquivos resultantes.
fonte
Você pode usar o
ex
comando, um editor Unix padrão (parte do Vim agora), por exemploexibir uma única linha (por exemplo, a segunda):
sintaxe sed correspondente:
sed -n '2p' file.txt
intervalo de linhas (por exemplo, 2-5 linhas):
sintaxe sed:
sed -n '2,5p' file.txt
da linha especificada até o final (por exemplo, do 5º ao final do arquivo):
sintaxe sed:
sed -n '2,$p' file.txt
vários intervalos de linhas (por exemplo, 2-4 e 6-8 linhas):
sintaxe sed:
sed -n '2,4p;6,8p' file.txt
Os comandos acima podem ser testados com o seguinte arquivo de teste:
Explicação:
+
ou-c
seguido pelo comando - execute o comando (vi / vim) após a leitura do arquivo,-s
- modo silencioso, também usa o terminal atual como saída padrão,q
seguido por-c
é o comando para sair do editor (adicione!
para fazer sair da força, por exemplo-scq!
).fonte
Se o seu número de linha for 100 para ler
fonte
Obter
ack
Instalação do Ubuntu / Debian:
Então corra:
Exemplo:
De
$ man ack
:fonte
--lines
parâmetro foi removido.O sed precisará ler os dados também para contar as linhas. A única maneira possível de um atalho seria o contexto / ordem no arquivo para operar. Por exemplo, se houvesse linhas de log anexadas com uma largura / hora / data fixas etc., você poderia usar o utilitário look unix para pesquisar binariamente nos arquivos por datas / horas específicas
fonte
Usar
Aqui você obterá o número da linha onde a partida ocorreu.
Agora você pode usar o seguinte comando para imprimir 100 linhas
ou você pode usar "sed" também
fonte
Com a
sed -e '1,N d; M q'
impressão das linhas N + 1 a M. Isso provavelmente é um pouco melhor,grep -C
pois não tenta corresponder as linhas a um padrão.fonte
-e
é opcional aqui.Com base na resposta do Sklivvz, aqui está uma boa função que você pode colocar em um
.bash_aliases
arquivo. É eficiente em arquivos enormes ao imprimir coisas pela frente do arquivo.fonte
Para exibir uma linha de a
<textfile>
por sua<line#>
, faça o seguinte:Se você deseja uma maneira mais poderosa de mostrar um intervalo de linhas com expressões regulares - não direi por que o grep é uma má idéia para fazer isso, deve ser bastante óbvio - essa expressão simples mostrará seu intervalo em um passe único que é o que você deseja ao lidar com arquivos de texto de ~ 20 GB:
(dica: se o seu regex tiver
/
, use algo como issom!<regex>!
)Isso imprimiria
<filename>
começando com a linha que corresponde<regex1>
até (e incluindo) a linha que corresponde<regex2>
.Não é preciso um assistente para ver como alguns ajustes podem torná-lo ainda mais poderoso.
Última coisa: o perl, por ser uma linguagem madura, possui muitas melhorias ocultas para favorecer a velocidade e o desempenho. Com isso em mente, torna a escolha óbvia para essa operação, uma vez que foi originalmente desenvolvida para lidar com grandes arquivos de log, texto, bancos de dados etc.
fonte
Você pode tentar este comando:
fonte
Fácil com perl! Se você deseja obter as linhas 1, 3 e 5 de um arquivo, diga / etc / passwd:
fonte
Surpreende-me apenas uma outra resposta (de Ramana Reddy) sugerida para adicionar números de linha à saída. A seguir, procura o número da linha necessária e pinta a saída.
fonte