Eu acho que todo mundo sabe que os utilitários de linha de cmd úteis Linux head
e tail
. head
permite imprimir as primeiras linhas X de um arquivo, tail
faz o mesmo, mas imprime o final do arquivo. Qual é um bom comando para imprimir no meio de um arquivo? algo como middle --start 10000000 --count 20
(imprima as 10.000 '000ª até as 10.000 '010ª linhas).
Estou procurando algo que lide com arquivos grandes com eficiência. Eu tentei tail -n 10000000 | head 10
e é terrivelmente lento.
Respostas:
Você pode acelerar isso um pouco assim:
Nesses comandos, a opção
-n
fazsed
com que "suprima a impressão automática do espaço do padrão". Op
comando "imprime [s] o espaço padrão atual" e oq
comando "Encerra imediatamente [s] o script sed sem processar mais nenhuma entrada ..." As aspas são dased
man
página .A propósito, seu comando
inicia na décima milionésima linha do final do arquivo, enquanto o comando "intermediário" parece começar na décima milionésima parte do início, o que seria equivalente a:
O problema é que, para arquivos não classificados com linhas de comprimento variável, qualquer processo precisará passar pelo arquivo contando novas linhas. Não há como atalho isso.
Se, no entanto, o arquivo for classificado (um arquivo de log com registros de data e hora, por exemplo) ou tiver linhas de comprimento fixo, você poderá procurar no arquivo com base na posição de bytes. No exemplo do arquivo de log, você pode fazer uma pesquisa binária por um intervalo de vezes como o meu script Python aqui *. No caso do arquivo com tamanho fixo de registro, é realmente fácil. Você apenas procura
linelength * linecount
caracteres no arquivo.* Eu mantenho a intenção de postar mais uma atualização para esse script. Talvez eu consiga resolver isso um dia desses.
fonte
sed
versão do Charles'middle
função:middle() { local s=$1 c=$2; shift 2; sed -n "$s,$(($s + $c -1))p; $(($s + $c))q" "$@"; }
. Ele manipulará vários argumentos de arquivo, nomes de arquivos com espaços, etc. Vários arquivos são processados juntos como se tivessem sido criados da mesma maneira quesed
normalmente (portanto, 1000 100 100 arquivo1 arquivo2 intermediário se estenderia do final do primeiro arquivo ao início do segundo se o primeiro tiver menos de 1100 linhas).middle startline count filename
ou vários nomes de arquivos:middle startline count file1 file2 file3
ou com redirecionamento:middle startline count < filename
ou em um tubo:some_command |
count` startline meio oucat file* | middle startline count
Eu descobri o seguinte uso de
sed
Espero que seja útil para alguém!
fonte
sed -n
argumento, o que o torna bastante legível.extract_lines(){sed -n "$1,+$2p" <file>}
que grava no stdout.Esta é minha primeira vez postando aqui! Enfim, este é fácil. Digamos que você queira extrair a linha 8872 do seu arquivo chamado file.txt. Aqui está como você faz isso:
cat -n arquivo.txt | grep '^ * 8872'
Agora, a questão é encontrar 20 linhas depois disso. Para conseguir isso, você faz
cat -n arquivo.txt | grep -A 20 '^ * 8872'
Para linhas ao redor ou antes, veja os sinalizadores -B e -C no manual grep.
fonte
cat -n file.txt | grep '^ *1'
produza todas as linhas que têm 1 no lado direito. Como gerar a linha 1 com esta técnica? Eu sei que posso dirigir -n 1 .... mas como usar grep?A resposta sedutora de Dennis é o caminho a percorrer. Mas usando apenas cabeça e cauda, sob o bash:
Isso varre as primeiras linhas de $ 1 + $ 2 duas vezes, então é muito pior do que a resposta de Dennis. Mas você não precisa se lembrar de todas aquelas cartas sed para usá-lo ....
fonte
$[...]
foi preterido, pelo menos no Bash. Além disso, você está perdendo um parâmetro de arquivo.middle 10 10 < /var/log/auth.log
.Use o comando a seguir para obter o intervalo específico de linhas
Aqui, debug.log é o meu arquivo, que consiste em uma falta de linhas e eu costumava imprimir as linhas do número da linha 1220974 para 1513793 em um arquivo test.log. espero que seja útil para capturar o intervalo de linhas.
fonte
Uma versão ruby oneliner.
Pode ser útil para alguém. As soluções com 'sed' fornecidas por Dennis e Dox são muito boas, mesmo porque parecem mais rápidas.
fonte
Você pode usar 'nl'.
fonte
Por exemplo, este awk imprimirá linhas entre 20 e 40
fonte
Se você conhece os números das linhas, diga que deseja obter as linhas 1, 3 e 5 de um arquivo, diga / etc / passwd:
fonte
Perl é rei:
fonte