Disons que j'ai un très gros fichier texte (environ 10.000.000 lignes). J'en ai besoin à grep
partir de la fin et enregistrer le résultat dans un fichier. Quel est le moyen le plus efficace d'accomplir cette tâche?
command-line
sed
awk
grep
efficiency
le chaos
la source
la source
tac
etgrep
pour réaliser ce que vous voulez.grep
dispose d’un--max-count (number)
commutateur qui abandonne après un certain nombre de correspondances, ce qui pourrait vous intéresser.Réponses:
tac / grep Solution
Ou un peu plus efficace:
Heure avec un fichier de 500 Mo:
Solution sed / grep :
Heure avec un fichier de 500 Mo: Abandonné après 10 minutes ou plus.
awk / grep Solution:
Heure avec un fichier de 500 Mo:
Solution perl / grep :
Heure avec un fichier de 500 Mo:
la source
sed
,awk
etperl
(avec cette méthode) ne sont pas acceptables car ils lisent le fichier depuis le début, ce qui est très inefficace. Je suppose que celatac
fait la bonne chose.< <(tac filename)
devrait être aussi rapide qu'un tuyau: dans les deux cas, les commandes sont exécutées en parallèle.tac
après le grep. Si vous avez un fichier de 10 000 000 lignes, avec seulement 2 correspondances, voustac
ne devrez inverser que 2 lignes et non 10 m.grep
va encore devoir passer par la chose entière de toute façon.tac
après legrep
, il lira un tuyau et ne pourra donc pas chercher. Cela le rendra moins efficace (ou échouera complètement) si le nombre de lignes trouvées est important.Cette solution pourrait aider:
la source
tac
est la commande GNU. Sur la plupart des autres systèmes, l'équivalent esttail -r
.tail -r
se limite à un petit nombre de lignes, cela peut poser problème.tail -r /etc/passwd
échoue avectail: invalid option -- 'r'
. J'utilise coreutils-8.21-21.fc20.x86_64.tac
(et seul GNU a tac) beaucoup d'autres Unicestail -r
. GNUtail
ne supporte pas-r
Celui-ci sort dès qu'il trouve le premier match:
Ce qui suit donne les 5 lignes avant et après les deux premiers matches:
Rappelez-vous de ne pas utiliser
-i
(insensible à la casse) à moins que vous n'ayez à le faire car cela ralentirait le grep.Si vous connaissez la chaîne exacte que vous recherchez, envisagez
fgrep
(chaîne fixe)la source
Si le fichier est vraiment gros, ne peut pas tenir dans la mémoire, je vais utiliser
Perl
avec le module File :: ReadBackwards deCPAN
:Ensuite:
la source
tac
.