Fusionner deux listes tout en supprimant les doublons

18

J'ai un système Linux intégré utilisant Busybox (OpenWRT) - les commandes sont donc limitées. J'ai deux fichiers qui ressemblent à:

premier fichier

aaaaaa
bbbbbb
cccccc
mmmmmm
nnnnnn

deuxième fichier

mmmmmm
nnnnnn
yyyyyy
zzzzzz

Je dois fusionner ces 2 listes en 1 fichier et supprimer les doublons. Je n'ai pas diff ( l' espace est limité) donc on arrive à utiliser la grande awk, sedet grep(ou d' autres outils qui pourraient être inclus dans une instance norme Busybox). Accéder à un fichier de fusion comme:

command1 > mylist.merge 
command2 mylist.merge > originallist

est totalement ok. Ce ne doit pas être une commande sur une seule ligne.

Fonctions actuellement définies dans l'instance de Busybox que j'utilise (OpenWRT par défaut): [, [[, arping, ash, awk, basename, brctl, bunzip2, bzcat, cat, chgrp, chmod, chown, chroot, clear, cmp, cp, crond, crontab, cut, date, dd, df, dirname, dmesg, du, echo, egrep, env, expr, false, fgrep, find, free, fsync, grep, gunzip, gzip, stop, head, hexdump, hostid, hwclock, id, ifconfig, init, insmod, kill, killall, klogd, less, ln, lock, logger, logread, ls, lsmod, md5sum, mkdir, mkfifo, mknod, mktemp, mount, mv, nc, netmsg, netstat, nice, nslookup, ntpd, passwd, pgrep, pidof, ping, ping6, pivot_root, pkill, poweroff, printf, ps, pwd, reboot, reset, rm, rmdir, rmmod, route, sed, seq, sh, sleep, tri, start-stop-daemon, strings, switch_root, sync, sysctl, syslogd, tail, tar, tee, telnet, telnetd, test,temps, haut, toucher, tr, traceroute, vrai, udhcpc, umount, uname, uniq, uptime, vconfig, vi, watchdog, wc, wget, which, xargs, yes, zcat

abeille
la source

Réponses:

28

je pense

sort file1 file2 | uniq
aaaaaa
bbbbbb
cccccc
mmmmmm
nnnnnn
yyyyyy
zzzzzz

fera ce que vous voulez.

Documentation supplémentaire: uniq sort

Jon
la source
8
Le tri busybox prend en charge l'indicateur unique -u.
Thor
@Thor: oooh cheers ce n'est pas un interrupteur que je connais.
10

En une seule commande sans aucun tuyau:

sort -u FILE1 FILE2

chercher

Supprimer les lignes en double

-> http://www.busybox.net/downloads/BusyBox.html

Gilles Quenot
la source
lequel est le meilleur pour les très gros fichiers? sort file1 file2 file3 file4 | uniqousort -u file1 file2 file3 file4
0x90
4

Une autre solution:

awk '!a[$0]++' file_1 file_2
nowy1
la source
J'ai vu que cela faisait une différence quel argument est venu en premier. Sinon, excellente solution, merci.
dezza
2

Pour trier selon une colonne clé, utilisez ce qui suit:

awk '!duplicate[$1,$2,$3]++' file_1 file_2

considérez ici la première, la deuxième et la troisième colonne comme votre clé primaire.

Prem Joshi
la source
1

Les fichiers de votre question sont triés.
Si les fichiers source sont effectivement triés, vous pouvez unifier et fusionner en une seule étape:

sort -um file1 file2 > mylist.merge

Pour le tri numérique (pas alphanumérique), utilisez:

sort -num file1 file2 > mylist.merge

Cela ne pouvait pas être fait sur place (redirigé vers un fichier source).

Si les fichiers ne sont pas triés, triez-les (ce tri peut être effectué sur place, en utilisant l'option de tri -o. Cependant, le fichier entier doit être chargé en mémoire):

sort -uo file1 file1
sort -uo file2 file2
sort -um file1 file2 > mylist.merge
mv mylist.merge originallist

Ce serait plus rapide que la "ligne de commande" plus simple pour tout trier:

cat file1 file2 | sort -u >mylist.merge

Cependant, cette ligne pourrait être utile pour les petits fichiers.

Isaac
la source