J'ai un script utilitaire en Python:
#!/usr/bin/env python
import sys
unique_lines = []
duplicate_lines = []
for line in sys.stdin:
if line in unique_lines:
duplicate_lines.append(line)
else:
unique_lines.append(line)
sys.stdout.write(line)
# optionally do something with duplicate_lines
Cette fonctionnalité simple (uniq sans avoir besoin de trier d'abord, ordre stable) doit être disponible sous la forme d'un simple utilitaire UNIX, n'est-ce pas? Peut-être une combinaison de filtres dans un tuyau?
Raison de demander: besoin de cette fonctionnalité sur un système sur lequel je ne peux pas exécuter python de n'importe où
Le blog UNIX Bash Scripting suggère :
awk '!x[$0]++'
Cette commande indique à awk les lignes à imprimer. La variable $0
contient l'intégralité du contenu d'une ligne et les crochets représentent un accès au tableau. Ainsi, pour chaque ligne du fichier, le noeud du tableau x
est incrémenté et la ligne imprimée si le contenu de ce noeud n'était pas (!
) défini auparavant.
Une réponse tardive - je viens de tomber sur une copie de ceci - mais peut-être la peine d’ajouter ...
Le principe de la réponse de @ 1_CR peut être écrit de manière plus précise, en utilisant cat -n
au lieu de awk
pour ajouter des numéros de ligne:
cat -n file_name | sort -uk2 | sort -nk1 | cut -f2-
cat -n
pour ajouter des numéros de lignesort -u
supprimer les données en doublesort -n
pour trier par numéro ajoutécut
pour supprimer la numérotation de ligneLa solution de Michael Hoffman ci-dessus est courte et douce. Pour les fichiers plus volumineux, une approche de transformation schwartzienne impliquant l'ajout d'un champ d'index à l'aide de awk suivi de plusieurs tours de tri et uniq implique moins de surcharge de mémoire. L'extrait suivant fonctionne en bash
awk '{print(NR"\t"$0)}' file_name | sort -t$'\t' -k2,2 | uniq --skip-fields 1 | sort -k1,1 -t$'\t' | cut -f2 -d$'\t'
Pour supprimer les doublons de 2 fichiers:
awk '!a[$0]++' file1.csv file2.csv
Merci 1_CR! J'avais besoin d'un "uniq -u" (supprimer entièrement les doublons) plutôt que d'uniq (laisser 1 copie des doublons). Les solutions awk et Perl ne peuvent pas vraiment être modifiées pour ce faire, vous pouvez le faire! J'aurais peut-être aussi besoin de moins de mémoire, car je vais unifier environ 100 000 000 lignes 8). Juste au cas où quelqu'un d'autre en aurait besoin, je viens de mettre un "-u" dans la partie uniq de la commande:
awk '{print(NR"\t"$0)}' file_name | sort -t$'\t' -k2,2 | uniq -u --skip-fields 1 | sort -k1,1 -t$'\t' | cut -f2 -d$'\t'
la commande uniq
fonctionne dans un alias même http://man7.org/linux/man-pages/man1/uniq.1.html
Vous pouvez maintenant consulter ce petit outil écrit en Rust: uq .
Il effectue le filtrage de l'unicité sans avoir à trier d'abord l'entrée, donc peut s'appliquer sur un flux continu.
Je voulais juste supprimer tous les doublons sur les lignes suivantes, pas partout dans le fichier. Alors j'ai utilisé:
awk '{
if ($0 != PREVLINE) print $0;
PREVLINE=$0;
}'