Existe-t-il un moyen de supprimer les lignes dupliquées dans un fichier sous Unix ?
Je peux le faire avec sort -u
y uniq
mais je veux utiliser les commandes sed
o awk
.
Est-ce possible ?
Existe-t-il un moyen de supprimer les lignes dupliquées dans un fichier sous Unix ?
Je peux le faire avec sort -u
y uniq
mais je veux utiliser les commandes sed
o awk
.
Est-ce possible ?
awk '!seen[$0]++' file.txt
seen
est un tableau associatif dans lequel AWK passera chaque ligne du fichier. Si une ligne n'est pas dans le tableau, alors seen[$0]
sera évaluée à false. Les !
est l'opérateur logique NOT et inversera le faux en vrai. AWK imprime les lignes où l'expression est évaluée à true.
En ++
incréments seen
de sorte que seen[$0] == 1
après la première fois qu'une ligne est trouvée et ensuite seen[$0] == 2
et ainsi de suite. AWK évalue tout sauf 0
y ""
(chaîne vide) à true. Si une ligne en double est placée dans seen
puis !seen[$0]
sera évaluée à false et la ligne ne sera pas écrite à la sortie.
Pour l'enregistrer dans un fichier, nous pouvons procéder comme suit awk '!seen[$0]++' merge_all.txt > output.txt
Une mise en garde importante : si vous devez faire cela pour plusieurs fichiers, et que vous ajoutez d'autres fichiers à la fin de la commande, ou que vous utilisez un joker le tableau 'seen' se remplira de lignes dupliquées provenant de TOUS les fichiers. Si vous voulez traiter chaque fichier indépendamment, vous devrez faire quelque chose comme for f in *.txt; do gawk -i inplace '!seen[$0]++' "$f"; done
@NickK9 ce dédoublonnage cumulatif sur plusieurs fichiers est impressionnant en soi. Jolie astuce
De http://sed.sourceforge.net/sed1line.txt : (Ne me demandez pas comment cela fonctionne ;-) )
# delete duplicate, consecutive lines from a file (emulates "uniq").
# First line in a set of duplicate lines is kept, rest are deleted.
sed '$!N; /^\(.*\)\n\1$/!P; D'
# delete duplicate, nonconsecutive lines from a file. Beware not to
# overflow the buffer size of the hold space, or else use GNU sed.
sed -n 'G; s/\n/&&/; /^\([ -~]*\n\).*\n\1/d; s/\n//; h; P'
'$!N ; /^(.*) \n\1 $/!P ; D' signifie "Si vous n'êtes pas à la dernière ligne, lisez une autre ligne. Maintenant, regardez ce que vous avez et si ce n'est pas un truc suivi d'une nouvelle ligne et ensuite le même truc, imprimez le truc. Maintenant, effacez le contenu (jusqu'à la nouvelle ligne)".
'G ; s/ \n /&&/ ; /^([ -~]* \n ).* \n\1 /d ; s/ \n // ; h ; P' signifie, en gros, "Ajoutez tout l'espace d'attente à cette ligne, puis si vous voyez une ligne dupliquée, jetez le tout, sinon copiez tout le bazar dans l'espace d'attente et imprimez la première partie (qui est la ligne que vous venez de lire)".
La phrase qui Andre Miller a posté fonctionne sauf pour les versions récentes de sed lorsque le fichier d'entrée se termine par une ligne blanche et aucun caractère. Sur mon Mac, mon processeur ne fait que tourner.
Il s'agit d'une boucle infinie si la dernière ligne est vide et ne contient aucun caractère :
sed '$!N; /^\(.*\)\n\1$/!P; D'
Il n'est pas suspendu, mais vous perdez la dernière ligne :
sed '$d;N; /^\(.*\)\n\1$/!P; D'
L'explication se trouve à la toute fin de la sed FAQ :
Le responsable de GNU sed a estimé qu'en dépit des problèmes de portabilité
Cela entraînerait la modification de la commande N pour l'impression (au lieu de l'impression).
supprimer) l'espace-modèle était plus cohérent avec les intuitions de l'utilisateur
sur la façon dont une commande pour "ajouter la ligne suivante" ought de se comporter.
Un autre argument en faveur du changement est que "{N;command;}" sera
supprime la dernière ligne si le fichier a un nombre impair de lignes, mais
imprime la dernière ligne si le fichier a un nombre pair de lignes.Pour convertir les scripts qui utilisaient l'ancien comportement de N (suppression de
l'espace du motif lorsqu'il atteint le FEO) à des scripts compatibles avec les
toutes les versions de sed, remplacer a lone "N ;" par "$d;N ;" .
Il existe un programme Gnome très pratique : FSlint
Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.
13 votes
Si vous voulez parler de doublons consécutifs, alors
uniq
suffit.0 votes
Et sinon, je crois que c'est possible avec
awk
mais sera assez gourmand en ressources sur des fichiers plus importants.0 votes
Doublons stackoverflow.com/q/24324350 y stackoverflow.com/q/11532157 ont des réponses intéressantes qui devraient idéalement être transférées ici.