Scal dwie listy podczas usuwania duplikatów

18

Mam wbudowany system linuksowy korzystający z Busybox (OpenWRT) - więc polecenia są ograniczone. Mam dwa pliki, które wyglądają:

pierwszy plik

aaaaaa
bbbbbb
cccccc
mmmmmm
nnnnnn

drugi plik

mmmmmm
nnnnnn
yyyyyy
zzzzzz

Muszę scalić te 2 listy w 1 plik i usunąć duplikaty. Nie mam diff (przestrzeń jest ograniczona), więc dostać się do wykorzystania wielkiego awk, sedi grep(lub innych narzędzi, które mogą być zawarte w standardowym przykład BusyBox). Przechodzenie do pliku scalania, takiego jak:

command1 > mylist.merge 
command2 mylist.merge > originallist

jest całkowicie w porządku. To nie musi być polecenie jednowierszowe.

Aktualnie zdefiniowane funkcje w przypadku Busybox, którego używam (domyślny OpenWRT): [, [[, arping, ash, awk, basename, brctl, bunzip2, bzcat, cat, chgrp, chmod, chown, chroot, clear, cmp, cp, crond, crontab, wytnij, data, dd, df, dirname, dmesg, du, echo, egrep, env, expr, false, fgrep, znajdź, wolny, fsync, grep, gunzip, gzip, halt, 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, sortowanie, start-stop-demon, ciągi, katalog_główny_switcha, synchronizacja, sysctl, syslogd, tail, tar, tee, telnet, telnetd, test,czas, góra, dotyk, tr, traceroute, true, udhcpc, umount, uname, uniq, uptime, vconfig, vi, watchdog, wc, wget, które, xargs, tak, zcat

uczący się
źródło

Odpowiedzi:

28

Myślę

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

zrobi co chcesz.

Dokumentacja dodatkowa: sortowanie uniq

Jon
źródło
8
sortowanie zajęte obsługuje unikalną flagę -u.
Thor
@Thor: oooh wiwaty, że to nie jest przełącznik, którego znam.
10

W jednym poleceniu bez potoku:

sort -u FILE1 FILE2

Szukaj

Pomiń zduplikowane linie

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

Gilles Quenot
źródło
który z nich jest lepszy w przypadku bardzo dużych plików? sort file1 file2 file3 file4 | uniqlubsort -u file1 file2 file3 file4
0x90
4

Inne rozwiązanie:

awk '!a[$0]++' file_1 file_2
nowy1
źródło
Widziałem, że to robi różnicę, który argument był pierwszy. W przeciwnym razie świetne rozwiązanie, dzięki.
dezza
2

Aby posortować według niektórych kluczowych kolumn, użyj:

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

tutaj rozważ pierwszą, drugą i trzecią kolumnę jako klucz podstawowy.

Prem Joshi
źródło
1

Pliki na twoje pytanie są posortowane.
Jeśli pliki źródłowe są rzeczywiście posortowane, możesz uniq i scalić w jednym kroku:

sort -um file1 file2 > mylist.merge

Do sortowania numerycznego (nie alfanumerycznego) użyj:

sort -num file1 file2 > mylist.merge

Tego nie można było zrobić w miejscu (przekierowano do jednego pliku źródłowego).

Jeśli pliki nie są posortowane, posortuj je (można to zrobić na miejscu, korzystając z opcji sortowania -o. Cały plik należy jednak załadować do pamięci):

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

Byłoby to szybsze niż prostszy „jeden wiersz poleceń” do sortowania wszystkich:

cat file1 file2 | sort -u >mylist.merge

Jednak ta linia może być przydatna w przypadku małych plików.

Izaak
źródło