Digamos, eu tenho um arquivo de texto muito grande (cerca de 10.000.000 linhas). Eu preciso grep
disso desde o final e salve o resultado em um arquivo. Qual é a maneira mais eficiente de realizar tarefas?
command-line
sed
awk
grep
efficiency
caos
fonte
fonte
tac
egrep
para conseguir o que deseja.grep
possui uma--max-count (number)
opção que interrompe após um certo número de correspondências, o que pode ser interessante para você.Respostas:
Solução tac / grep
Ou um pouco mais eficaz:
Tempo com um arquivo de 500 MB:
Solução sed / grep :
Tempo com um arquivo de 500 MB: interrompido após mais de 10 minutos.
Solução awk / grep :
Tempo com um arquivo de 500 MB:
Solução perl / grep :
Tempo com um arquivo de 500 MB:
fonte
sed
,awk
eperl
(com esse método) não estão OK, pois eles lêem o arquivo desde o início, o que é muito ineficiente. Suponho quetac
faça a coisa certa.< <(tac filename)
Deve ser tão rápido quanto um pipe: nos dois casos, os comandos são executados em paralelo.tac
depois do grep. Se você tiver um arquivo de 10.000.000 de linhas, com apenas 2 correspondências,tac
precisará reverter 2 linhas, e não 10m.grep
ainda vai ter que passar por tudo de qualquer maneira.tac
depois dogrep
, ele estará lendo de um cano e, portanto, não poderá procurar. Isso tornará menos eficiente (ou falhará completamente) se o número de linhas encontradas for grande.Esta solução pode ajudar:
fonte
tac
é o comando GNU. Na maioria dos outros sistemas, o equivalente étail -r
.tail -r
é limitado a um pequeno número de linhas, isso pode ser um problema.tail -r /etc/passwd
falha comtail: invalid option -- 'r'
. Estou usando o coreutils-8.21-21.fc20.x86_64.tac
(e apenas o GNU possui tac) muitos outros Unicestail -r
. O GNUtail
não oferece suporte-r
Este sai assim que encontra a primeira correspondência:
A seguir, são apresentadas as 5 linhas antes e depois das duas primeiras partidas:
Lembre-se de não usar
-i
(sem distinção entre maiúsculas e minúsculas), a menos que você precise, pois isso desacelerará o grep.Se você souber a string exata que está procurando, considere
fgrep
(String fixa)fonte
Se o arquivo é muito grande, não pode caber na memória, vou usar
Perl
com File :: ReadBackwards módulo deCPAN
:Então:
fonte
tac
.