2013-06-01 25 views
10

Mam około 350 plików tekstowych (a każdy plik ma około 75 MB). Próbuję połączyć wszystkie pliki i usunąć zduplikowane wpisy. Plik znajduje się w następującym formacie:łączenie wielu plików tekstowych i usuwanie duplikatów.

ip1,dns1 
ip2,dns2 
... 

napisałem mały skrypt, aby zrobić to

#!/bin/bash 
for file in data/* 
do 
    cat "$file" >> dnsFull 
done 
sort dnsFull > dnsSorted 
uniq dnsSorted dnsOut 
rm dnsFull dnsSorted 

robię to często przetwarzanie i zastanawiałem się, czy jest coś mogę zrobić, aby poprawić przetwarzanie następnym razem, kiedy go uruchomię. Jestem otwarty na każdy język programowania i sugestie. Dzięki!

+0

możesz również dać sort -ma spróbować -> będzie sortować poszczególne pliki i scalać je odpowiednio więc powinno zaoszczędzić sporo czasu .... opcja -m była dostępna espl dla takiego scenariusza ... to znaczy -m plik * | uniq -u – nsd

Odpowiedz

30

Po pierwsze, nie używasz pełnej mocy cat. Pętla może być zastąpiona przez tylko

cat data/* > dnsFull 
przy założeniu, że plik jest początkowo pusty.

Następnie są wszystkie pliki tymczasowe, które zmuszają programy do oczekiwania na dyski twarde (zwykle najwolniejsze części w nowoczesnych systemach komputerowych). Użyj rurociągu:

cat data/* | sort | uniq > dnsOut 

To wciąż rozrzutny od sort sam może robić to, co używasz cat i uniq dla; cały skrypt może być zastąpiony przez

sort -u data/* > dnsOut 

Jeśli to nadal nie jest wystarczająco szybki, to uświadomić sobie, że sortowanie zajmuje O (n lg n) czasu podczas deduplikacji można zrobić w czasie liniowym z Awk:

awk '{if (!a[$0]++) print}' data/* > dnsOut 
+0

Bardzo dobrze powiedziane, dzięki. – drk

+5

Zauważ, że ostateczny awk można uprościć do "awk"! A [0 0] ++ "dane/*' –

+1

Usunąłem moją odpowiedź perla, ponieważ 350 * 75 MB = więcej niż 26 GB - sortowanie w pamięci (np. Awk) może spowodować za dużo wymiany pamięci. – jm666

Powiązane problemy