J'ai un gros fichier contenant une chaîne sur chaque ligne. Je voudrais pouvoir déterminer rapidement si une chaîne est dans le fichier. Idéalement, cela se ferait en utilisant un algorithme de type binaire chop.
Certains googleurs ont révélé la look
commande avec le -b
drapeau qui promet de localiser et de sortir toutes les chaînes commençant par un préfixe donné en utilisant un algorithme de recherche binaire. Malheureusement, cela ne semble pas fonctionner correctement et renvoie des résultats nuls pour les chaînes que je connais dans le fichier (elles sont correctement renvoyées par la grep
recherche équivalente ).
Quelqu'un connaît-il un autre utilitaire ou stratégie pour rechercher ce fichier efficacement?
look
commande fonctionne correctement, car l'apparence semble ignorer les paramètres régionaux et utilise uniquement C comme le tri en dur, j'ai également ouvert un bogue à cause de ce comportement déroutant: bugzilla.kernel.org/show_bug.cgi?id=198011look -b
a échoué pour moi avec une erreurFile too large
. Je pense qu'il essaie de lire le tout en mémoire.Réponses:
Il y a une différence essentielle entre
grep
etlook
:Sauf indication contraire explicite,
grep
trouvera des motifs même quelque part dans les lignes. Pourlook
la page de manuel déclare:Je n'utilise pas
look
très souvent, mais cela a bien fonctionné sur un exemple trivial que je viens d'essayer.la source
egrep "^TEST" sortedlist.txt | wc -l
j'obtiens 41 289 résultats. Cependant, leslook
commandes équivalenteslook -b TEST sortedlist.txt | wc -l
ne donnent que des résultats de 1995. Je me demande presque s'il y a un buglook
.look
- être utilise des paramètres de classement différents de ceux du programme que vous avez utilisé pour trier le fichier.Peut-être une petite réponse tardive:
Sgrep vous aidera.
Sgrep (grep trié) recherche dans les fichiers d'entrée triés les lignes qui correspondent à une clé de recherche et sort les lignes correspondantes. Lors de la recherche de fichiers volumineux, sgrep est beaucoup plus rapide que grep Unix traditionnel, mais avec des restrictions importantes.
Vous pouvez télécharger la source ici: https://sourceforge.net/projects/sgrep/?source=typ_redirect
et les documents ici: http://sgrep.sourceforge.net/
Autrement:
Je ne sais pas quelle est la taille du fichier. Peut-être devriez-vous essayer en parallèle:
/programming/9066609/fastest-possible-grep
Je fais toujours du grep avec des fichiers dont la taille est> 100 Go, ça marche bien.
la source
sudo apt-get install sgrep
pour obtenir sgrep, le sgrep dans les dépôts buntu n'est pas réellement ce sgrep, je ne suis pas sûr que ce soit la même chose.Vous pouvez hacher le fichier en morceaux, puis grep juste la pièce que vous vouliez:
alors la recherche ressemblerait à:
Cela fait deux choses:
la source
sgrep peut fonctionner pour vous:
La page du projet http://sgrep.sourceforge.net/ dit:
Pour l'insertion cependant, je pense qu'il n'y a pas de meilleure solution que d'utiliser une base de données: /programming/10658380/shell-one-liner-to-add-a-line-to-a-sorted-file/ 33859372 # 33859372
la source
sgrep
dans les référentiels Ubuntu est en fait ce sgrep , qui est conçu pour "rechercher un modèle dans un fichier" et n'a rien à voir avec la recherche binaire.Si vous le voulez vraiment rapide (O (1) rapide), vous pouvez créer un ensemble de hachage à examiner. Je ne pouvais pas trouver une implémentation qui me permettrait de stocker un ensemble de hachage pré-construit dans un fichier et de le sonder sans avoir à lire le fichier entier en mémoire, alors j'ai roulé le mien .
Construisez l'ensemble de hachage (
-b
/--build
):Sondez l'ensemble de hachage (
-p
/--probe
):… Ou avec une chaîne à rechercher sur l'entrée standard:
Vous pouvez désactiver la sortie de
--probe
avec l' option-q
/--quiet
si vous êtes uniquement intéressé par l'état de sortie:Pour plus d'options, voir la description d'utilisation accessible via l' option
-h
/--help
ou leREADME
fichier d' accompagnement .la source