J'ai "test1.csv" et il contient
200,400,600,800
100,300,500,700
50,25,125,310
et test2.csv et il contient
100,4,2,1,7
200,400,600,800
21,22,23,24,25
50,25,125,310
50,25,700,5
maintenant
diff test2.csv test1.csv > result.csv
est différent de
diff test1.csv test2.csv > result.csv
Je ne sais pas quel est le bon ordre mais je veux autre chose, les deux commandes ci-dessus produiront quelque chose comme
2 > 100,4,2,1,7
3 2,3c3,5
4 < 100,300,500,700
5 < 50,25,125,310
6 \ No newline at end of file
7 ---
8 > 21,22,23,24,25
9 > 50,25,125,310
Je veux afficher uniquement la différence, donc results.csv devrait ressembler à ceci
100,300,500,700
100,4,2,1,7
21,22,23,24,25
50,25,700,5
J'ai essayé diff -q
et diff -s
mais ils n'ont pas fait l'affaire. L'ordre n'a pas d'importance, ce qui compte, c'est que je ne veux voir que la différence, pas de> ni <ni d'espace vide.
grep -FvF
a fait l'affaire sur les petits fichiers pas sur les gros
le premier fichier contient plus de 5 millions de lignes, le second fichier en contient 1 300.
donc results.csv devrait donner environ 4 998 700 lignes
J'ai également essayé grep -F -x -v -f
ce qui n'a pas fonctionné.
50,25,125,310
est commun aux deux fichiers .. vous devez supprimer cela de votre sortie souhaitée ..Réponses:
Cela ressemble à un travail pour
comm
:Comme expliqué dans
man comm
:Ainsi,
-3
cela signifie que seules les lignes uniques à l'un des fichiers seront imprimées. Cependant, ceux-ci sont en retrait selon le fichier dans lequel ils ont été trouvés. Pour supprimer l'onglet, utilisez:Dans ce cas, vous n'avez même pas vraiment besoin de trier les fichiers et vous pouvez simplifier ce qui précède pour:
la source
200,[...]
ligne hein? :)Utilisation
grep
avecbash
substitution de processus:Pour enregistrer la sortie sous
results.csv
:<()
est lebash
modèle de substitution de processusgrep -vFf test2.csv test1.csv
trouvera les lignes uniques à seulementtest1.csv
grep -vFf test1.csv test2.csv
trouvera les lignes uniques à seulementtest2.csv
Enfin, nous résumons les résultats en
cat
Ou, comme l'a suggéré Oli , vous pouvez également utiliser le regroupement de commandes:
Ou exécutez-les simplement l'un après l'autre, car ils écrivent tous les deux sur STDOUT, ils seront finalement ajoutés:
la source
cat
deux commandes redirigées? Pourquoi ne pas simplement exécuter l'un puis l'autre?grep ... ; grep ...
ou{ grep ... ; grep ... ; }
si vous vouliez faire quelque chose avec la sortie collective.Si l'ordre des lignes n'est pas pertinent, utilisez
awk
ouperl
:Utilisez
grep
pour obtenir les lignes communes et les filtrer:Le grep interne obtient les lignes communes, puis le grep externe trouve les lignes qui ne correspondent pas à ces lignes communes.
la source
sort | uniq -u
, ce qui donne la mauvaise réponse lorsqu'un fichier contient des lignes en double. Pour grep, je dirais "intérieur" / "extérieur", pas "interne" / "externe".awk
imprimera et ce que lecomm -3
et lesdiff
réponses seront imprimées.comm -3
. Je ne vois aucune raison pour laquelle je devrais expliquer cela. Si vous souhaitez modifier une note, n'hésitez pas.Utilisez les
--*-line-format=...
options dediff
Vous pouvez dire
diff
exactement ce dont vous avez besoin - expliqué ci-dessous:Il est possible de spécifier la sortie de diff d'une manière très détaillée, semblable à un
printf
format numérique.Les lignes du premier fichier,
test1.csv
sont appelées "anciennes" lignes, et les lignes du secondtest2.csv
, sont des "nouvelles" lignes. Cela a du sens quanddiff
est utilisé pour voir ce qui a changé dans un fichier.Les options dont nous avons besoin sont celles permettant de définir le format des "anciennes" lignes, des "nouvelles" lignes et des lignes "inchangées".
Les formats dont nous avons besoin sont très simples:
pour les lignes modifiées, nouvelles et anciennes, nous voulons afficher uniquement le texte des lignes.
%L
est le symbole de format du texte de la ligne.Pour les lignes inchangées, nous ne voulons rien montrer.
Avec cela, nous pouvons écrire des options comme
--old-line-format='%L'
, et tout assembler, en utilisant vos données d'exemple:Notes sur les performances
Parce que les fichiers ont une taille différente, essayez d'échanger les fichiers d'entrée si cela n'a pas d'importance, il se peut que le fonctionnement interne de
diff
puisse gérer une manière mieux que l'autre. Mieux vaut soit avoir besoin de moins de mémoire, soit moins de calculs.Il existe une option d'optimisation pour l'utilisation
diff
avec des fichiers volumineux:--speed-large-files
. Il utilise des hypothèses sur la structure du fichier, il n'est donc pas clair si cela vous aide dans votre cas, mais cela vaut la peine de l'essayer.Les options de format sont décrites ci-
man diff
dessous--LTYPE-line-format=LFMT
.la source
Comme l'ordre n'a pas besoin d'être conservé, il suffit de:
sort test1.csv test2.csv
: fusionne et trietest1.csv
ettest2.csv
uniq -u
: imprime uniquement les lignes sans doublonla source
diff
résultat.