J'utilise egrep ( grep -E
) avec un fichier PATTERN. ( -f path/to/file
).
Cela se fait dans une boucle infinie sur un flux de texte. Cela implique que je ne peux pas accumuler et passer TOUTES les entrées à grep à la fois (comme *.log
).
Existe-t-il un moyen de faire grep "enregistrer" le NFA qu'il construit à partir du fichier PATTERN pour l'utiliser pour sa prochaine exécution?
J'ai cherché sur Google et j'ai lu la documentation sans succès.
Je vais essayer de l'expliquer un peu plus. J'ai besoin de localiser un nombre fixe de chaînes avec des expressions rationnelles (cela ne fait pas partie d'une question mais n'hésitez pas à suggérer le contraire) telles que les adresses IP, les domaines, etc. La recherche se fait sur un flux provenant d'Internet. Vous pouvez le considérer comme un flux de texte. Je ne peux pas utiliser grep
sur toutes les entrées car c'est un flux. Je peux accumuler un morceau de flux et l'utiliser grep
dessus (donc ne pas utiliser grep
sur chaque ligne) mais cela est également limité (disons pendant 30 secondes).
Je sais grep
est en train de construire un NFA à partir de tous ses modèles (dans mon cas à partir d'un fichier). Donc ma question ici est: puis-je dire grep
de sauvegarder ce NFA pour la prochaine exécution, car il ne va pas changer? Cela me ferait gagner du temps pour construire cette NFA à chaque fois.
grep
par ligne de texte? D'où vient le texte? Seraittail -f
une option?grep
sur ce morceau.grep
plusieurs fois. Peut-être lié: pourquoi la mise en correspondance de 1250 chaînes avec des motifs de 90k est-elle si lente?grep
est censé fonctionner sur un flux de texte, je ne comprends toujours pas pourquoi vous devez exécuter plusieurs instances. Pourquoi ne pouvez-vous pas alimenter tous ces éléments dans la mêmegrep
instance? Pourquoi avez-vous besoin de les accumuler avant de les nourrirgrep
?Réponses:
Non, il n'y a rien de tel. Généralement, le coût de démarrage
grep
( lancer un nouveau processus, charger l'exécutable, bibliothèque partagée, liaison dynamique ...) serait beaucoup plus élevé que la compilation des regexps, donc ce type d'optimisation n'aurait aucun sens.Bien voir pourquoi Pourquoi la mise en correspondance de 1250 chaînes contre des motifs de 90k est-elle si lente? à propos d'un bug dans certaines versions de GNU
grep
qui le rendrait particulièrement lent pour un grand nombre d'expressions régulières.Ici, vous pouvez peut-être éviter d'exécuter
grep
plusieurs fois en alimentant vos morceaux dans la mêmegrep
instance, par exemple en l'utilisant comme un co-processus et en utilisant un marqueur pour détecter la fin. Aveczsh
et GNUgrep
etawk
implémentations autres quemawk
:Bien qu'il soit plus simple de faire le tout avec
awk
ou à laperl
place.Mais si vous n'avez pas besoin de la
grep
sortie pour entrer dans différents fichiers pour différents morceaux, vous pouvez toujours faire:la source
grep
tel quel. Merci.Savez-vous que les pipelines se bloquent? Si vous dirigez quelque chose vers grep et que toutes les entrées ne sont pas disponibles, grep attendra qu'il soit disponible, puis continuera comme si l'entrée était là tout le temps.
EDIT: Le fonctionnement des pipelines, par exemple avec,
cmd1 | cmd2
est que les deux programmes démarreront en même temps, avec par exemple un "tampon de bloc" de 65 536 octets entre eux. Lorsquecmd2
tente de lire et que le tampon est vide, il attendra qu'un morceau soit disponible. Quandcmd1
essaie d'écrire et que le tampon est plein, il attendra jusqu'àcmd2
ce qu'il le lise.D'après ce que je peux lire, il n'est pas nécessaire de couper l'entrée en morceaux et de les passer à grep séparément. C'est déjà fait automatiquement.
EDIT2:
grep
devrait également imprimer les résultats dès qu'il les trouve dans le flux. Il n'est pas nécessaire que le flux se termine avant d'obtenir vos résultats.la source
Vous pouvez peut-être "utiliser grep sur toutes les entrées"? Vous
nc
utilisez (netcat), ou viascript
ou via d'autres outils similaires? Surtout si votre fichier de signatures est de taille gérable (disons moins de 1000 regexps).Premier exemple : vous pouvez
egrep
une connexion en streaming: (ici l'exemple montré avecnc
, mais d'autres pourraient s'appliquer)(note: vous pouvez même:
touch /some/path/results.gz
avant de lancer lanc
commande, et avoirtail -f
sur ce fichier (vide) pour ne rien rater. Quoi qu'il en soit, le results.gz contiendra tout ce que vous vouliez attraper)deuxième exemple : Vous pourriez même
egrep
sur une session shell en cours d'exécution (et montrant une autre façon de suivre la progression):egrep
est une version très efficace degrep
, sur la plupart des systèmes (voir quelques infos intéressantes sur: https://swtch.com/~rsc/regexp/regexp1.html )la source
s
est beaucoup, bouillie plus lente que la correspondancesomething
et cela est beaucoup plus lent que la correspondancesomething even much longer
(cette dernière permettant à la correspondance d'expression régulière de sauter plus grande) sur des fichiers volumineux, il "divise" essentiellement le temps de l'analyser par le rapport de longueur (c'est-à-dire que le fait de saluer 1 caractère connu est presque 40 fois plus lent que de correspondre à une chaîne de 40 caractères connus. Je n'ai pas t prof mais c'est vraiment perceptible.)