GNU/Linux >> Tutoriels Linux >  >> Linux

Sélectionner les lignes du fichier texte dont les identifiants sont répertoriés dans un autre fichier ?

J'utilise beaucoup de grep awk sort dans mon shell unix pour travailler avec des fichiers texte de colonne séparés par des tabulations de taille moyenne (environ 10 à 100 millions de lignes). À cet égard, le shell Unix est ma feuille de calcul.

Mais j'ai un gros problème, c'est de sélectionner des enregistrements avec une liste d'identifiants.

Avoir table.csv fichier au format idtfootbar... et ids.csv fichier avec la liste des identifiants, sélectionnez uniquement les enregistrements de table.csv avec l'identifiant présent dans ids.csv .

genre de https://stackoverflow.com/questions/13732295/extract-all-lines-from-text-file-based-on-a-given-list-of-ids mais avec shell, pas perl.

grep -F produit évidemment des faux positifs si les identifiants sont de largeur variable.
join est un utilitaire que je ne pourrais jamais comprendre. Tout d'abord, cela nécessite un tri alphabétique (mes fichiers sont généralement triés par ordre numérique), mais même dans ce cas, je ne peux pas le faire fonctionner sans me plaindre d'un ordre incorrect et sauter certains enregistrements. Donc je n'aime pas ça.
grep -f contre le fichier avec ^idt -s est très lent lorsque le nombre d'identifiants est important.
awk est encombrant.

Existe-t-il de bonnes solutions pour cela? Des outils spécifiques pour les fichiers séparés par des tabulations ? Des fonctionnalités supplémentaires seront également les bienvenues.

UPD :sort corrigé -> join

Réponse acceptée :

Je suppose que vous vouliez dire grep -f pas grep -F mais vous avez en fait besoin d'une combinaison des deux et de -w :

grep -Fwf ids.csv table.csv

La raison pour laquelle vous obteniez des faux positifs est (je suppose que vous n'avez pas expliqué) parce que si un identifiant peut être contenu dans un autre, alors les deux seront imprimés. -w supprime ce problème et -F s'assure que vos modèles sont traités comme des chaînes et non comme des expressions régulières. Depuis man grep :

   -F, --fixed-strings
          Interpret PATTERN as a  list  of  fixed  strings,  separated  by
          newlines,  any  of  which is to be matched.  (-F is specified by
          POSIX.)
   -w, --word-regexp
          Select  only  those  lines  containing  matches  that form whole
          words.  The test is that the matching substring must  either  be
          at  the  beginning  of  the  line,  or  preceded  by  a non-word
          constituent character.  Similarly, it must be either at the  end
          of  the  line  or  followed by a non-word constituent character.
          Word-constituent  characters  are  letters,  digits,   and   the
          underscore.

   -f FILE, --file=FILE
          Obtain  patterns  from  FILE,  one  per  line.   The  empty file
          contains zero patterns, and therefore matches nothing.   (-f  is
          specified by POSIX.)

Si vos faux positifs sont dus au fait qu'un ID peut être présent dans un champ non-ID, parcourez plutôt votre fichier :

while read pat; do grep -w "^$pat" table.csv; done < ids.csv

ou, plus rapide :

xargs -I {} grep "^{}" table.csv < ids.csv

Personnellement, je ferais cela en perl cependant :

perl -lane 'BEGIN{open(A,"ids.csv"); while(<A>){chomp; $k{$_}++}} 
            print $_ if defined($k{$F[0]}); ' table.csv

Linux
  1. Comment supprimer les lignes en double dans un fichier texte ?

  2. Supprimer efficacement les premières lignes d'un fichier texte ?

  3. Modifier un courrier entrant de Text/plain à Text/html ?

  4. Comment supprimer plusieurs lignes aléatoires d'un fichier texte à l'aide de Sed ?

  5. Créer des données de lecture de texte à partir d'un fichier ?

Comment créer des répertoires à partir d'un fichier texte sous Linux

Comment imprimer des lignes dupliquées dans un fichier texte sous Linux

Comment supprimer des fichiers répertoriés dans un autre fichier sous Linux

Comment supprimer les lignes qui apparaissent sur le fichier B d'un autre fichier A ?

Supprimer les N premières lignes d'un fichier journal actif

Comment afficher certaines lignes d'un fichier texte sous Linux ?