Si l'ordre des lignes dans la sortie n'a pas d'importance, cela fonctionne :
sort file_a file_b|uniq -u
Cela trie les deux fichiers, puis uniq
peut facilement trouver les doublons et les supprimer.
El -u
sur le uniq
moyens de commandement remove duplicates
.
La complexité du triage est de O(n.log(n)) (en supposant que sort
utilise quicksort) et O(n) pour la suppression des doublons sur les lignes triées, donc ce sera plus rapide que la version grep (O(n²)) si les fichiers sont volumineux. La version de grep ressemble à ceci :
for each line l1 in f1
for each line l2 in f2
if l1 == l2
break
end if
end for
output l1 if no l2 == l1
endfor
Voici un benchmark rapide avec 15K entrées en f1 et 7.5K en f2 :
# add lines with number from 1 to 15000; randomly sorted; to f1
for i in $(seq 1 15000); do echo "$i"; done|sort -R > f1
# add lines with number from 1 to 15000 (with step 2); randomly sorted; to f2
for i in $(seq 1 2 15000); do echo "$i"; done|sort -R > f2
# sort|uniq -u method:
$ time sort f1 f2|uniq -u > /dev/null
real 0m0.067s
user 0m0.064s
sys 0m0.004s
# comm method (requires to sort both files separately first):
time (sort f1 > f1.sorted; sort f2 > f2.sorted; comm -2 -3 f1.sorted f2.sorted) > /dev/null
real 0m0.070s
user 0m0.068s
sys 0m0.000s
# grep method:
time grep -v -x -f f2 f1 > /dev/null
real 0m16.528s
user 0m16.457s
sys 0m0.048s
Ainsi, le sort|uniq
ne prend que 0.07s
tandis que le grep
version prend plus de 16s
et ce temps augmentera de façon exponentielle avec la taille des fichiers.
5 votes
Duplication possible de Supprimer les lignes d'un fichier qui apparaissent dans un autre fichier
0 votes
Si vous cherchez à supprimer les lignes d'un fichier qui "contiennent même" des chaînes de caractères d'un autre fichier (par exemple, des correspondances partielles), voir unix.stackexchange.com/questions/145079/