Existe-t-il un outil pouvant obtenir des lignes contenues dans le fichier A, mais pas le fichier B? Je pourrais faire un petit script simple avec, par exemple, Perl, mais si quelque chose comme ça existe déjà, je vais économiser mon temps à partir de maintenant.
command-line
Marguerite
la source
la source
Réponses:
Oui. L'
grep
outil standard de recherche de chaînes de texte dans les fichiers peut être utilisé pour soustraire toutes les lignes d'un fichier à un autre.Cela fonctionne en utilisant chaque ligne de fileB comme un motif (
-f fileB
) et en la traitant comme une chaîne simple à faire correspondre (pas une expression régulière régulière) (-F
). Vous forcez la correspondance sur toute la ligne (-x
) et n'imprimez que les lignes qui ne correspondent pas (-v
). Par conséquent, vous imprimez dans le fichier A les lignes qui ne contiennent pas les mêmes données que toutes les lignes du fichier B.L'inconvénient de cette solution est qu'elle ne prend pas en compte l'ordre des lignes et que, si vous saisissez des lignes en double à différents endroits, vous risquez de ne pas obtenir ce que vous attendiez. La solution à cela consiste à utiliser un véritable outil de comparaison tel que
diff
. Vous pouvez le faire en créant un fichier diff avec la valeur de contexte à 100% des lignes du fichier, puis en l’analysant uniquement pour les lignes qui seraient supprimées si le fichier A était converti en fichier B. (Remarque: cette commande supprime également le fichier diff. le formatage après avoir obtenu les bonnes lignes.)la source
-u
argument ne tient en fait un paramètre d'un nombre aussi longtemps qu'il est pas suivi d'un espace. L'avantage de la façon dont je l'ai eu avant est que cela fonctionnera avec ou sans valeur, vous pouvez donc utiliser quelque chose dans cette routine de sous-commande qui renvoie non-sortie. Les majuscules -U nécessitent par contre un argument.diff
pipeline fonctionne un plaisir merci.grep
besoin. Exemple:grep -F -x -v -f <(sort fileB) <(sort fileA)
diff
est que cette position dans le fichier est prise en compte.La réponse dépend beaucoup du type et du format des fichiers que vous comparez.
Si les fichiers que vous comparez sont des fichiers texte triés, l'outil GNU écrit par Richard Stallman et Davide McKenzie, appelé,
comm
peut effectuer le filtrage souhaité. Cela fait partie des coreutils.Exemple
Disons que vous avez les 2 fichiers suivants:
Lignes dans le fichier
b
qui ne sont pas dans le fichiera
:la source
comm
; malheureusement,comm
nécessite des fichiers triés<()
? Cela fonctionne et je comprends, mais y a-t-il un nom pour cette étrangeté?<()
est également appelé substitution de processus .comm
a été écrit vers 1973 par une personne des Bell Labs et non par la firme. Vous faites référence à la mise en oeuvre de GNU qui est venue beaucoup plus tard. Il y a eu beaucoup d'implémentations différentes des utilitaires Unix au cours des années.de stackoverflow ...
-23 supprime les lignes qui se trouvent dans les deux fichiers, ou uniquement dans le fichier 2. Les fichiers doivent être triés (ils le sont dans votre exemple), sinon, dirigez-les d'abord par tri ...
Voir la page de man ici
la source
Les méthodes grep et comm (avec sort) prennent beaucoup de temps sur les gros fichiers. SiegeX et ghostdog74 ont partagé deux excellentes méthodes awk pour extraire des lignes uniques à l'un des deux fichiers sur Stack Overflow:
la source
Si les fichiers sont volumineux et que vos entrées ne sont pas personnalisées, grep prend beaucoup trop de temps. Une alternative rapide serait
[fichier2-fichier1 résultats à l'écran, pipe à fichier, etc.]
Changer
>
pour<
obtenir la soustraction opposée.rm 1 2
la source
Vous pouvez également considérer vimdiff, il met en évidence les différences entre les fichiers dans un éditeur vim
la source