J'ai deux fichiers (disons a.txt
et b.txt
), qui ont tous deux une liste de noms. J'ai déjà exécuté sort
sur les deux fichiers.
Maintenant, je veux trouver des lignes de a.txt
qui ne sont pas présents dans b.txt
.
(J'ai passé beaucoup de temps à trouver la réponse à cette question, donc à documenter pour référence future)
La commande que vous devez utiliser n’est pas diff
mais comm
comm -23 a.txt b.txt
Par défaut, comm
génère 3 colonnes: gauche seulement, droite seulement, les deux. Le -1
, -2
et -3
_ supprime ces colonnes.
Alors, -23
masque les colonnes à droite et les deux, montrant les lignes qui apparaissent uniquement dans le premier fichier (à gauche).
Si vous voulez trouver des lignes qui apparaissent dans les deux cas, vous pouvez utiliser -12
, qui masque les colonnes gauche seulement et droite seulement, ne vous laissant que la colonne les deux.
La réponse simple n'a pas fonctionné pour moi car je n'avais pas réalisé que comm
correspondait ligne par ligne. Les lignes dupliquées dans un fichier seront donc imprimées comme n'étant pas existantes dans l'autre. Par exemple, si fichier1 contenait:
Alex
Bill
Fred
Et file2 contenait:
Alex
Bill
Bill
Bill
Fred
Alors comm -13 file1 file2
Produirait:
Bill
Bill
Dans mon cas, je voulais seulement savoir que chaque chaîne de file2 existait dans file1, quel que soit le nombre de fois que cette ligne se soit produite dans chaque fichier.
Solution 1: utilisez l'indicateur -u
(Unique) pour sort
:
comm -13 <(sort -u file1) <(sort -u file2)
Solution 2: (la première réponse "de travail" que j'ai trouvée) de nix.stackexchange :
fgrep -v -f file1 file2
Notez que si fichier2 contient des lignes en double qui n'existent pas du tout dans fichier1, fgrep
produira chacune des lignes en double. Notez également que mes tests totalement non scientifiques sur un seul ordinateur portable pour un seul ensemble de données (assez volumineux) ont montré que la solution 1 (avec comm
) était presque 5 fois plus rapide que la solution 2 (avec fgrep
).
Je ne suis pas sûr de savoir pourquoi il a été dit que diff
ne devrait pas être utilisé. Je l’utiliserais pour comparer les deux fichiers, puis pour afficher uniquement les lignes qui se trouvent dans le fichier de gauche mais pas dans le fichier de droite. Ces lignes sont signalées par diff avec <
donc il suffit de grep ce symbole au début de la ligne
diff a.txt b.txt | grep \^\<
Si les fichiers ne sont pas encore triés, vous pouvez utiliser:
comm -23 <(sort a.txt) <(sort b.txt)