2013-06-01 4 views
10

У меня около 350 текстовых файлов (и каждый файл составляет около 75 МБ). Я пытаюсь объединить все файлы и удалить повторяющиеся записи. Файл находится в следующем формате:объединить несколько текстовых файлов и удалить дубликаты

ip1,dns1 
ip2,dns2 
... 

Я написал небольшой скрипт, чтобы сделать это

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

Я делаю эту обработку часто и было интересно, если есть что-то я мог бы сделать, чтобы улучшить обработка в следующий раз при запуске. Я открыт для любого языка программирования и предложений. Благодаря!

+0

вы также можете дать sort -ma try -> он будет сортировать отдельные файлы и объединять их соответственно, следовательно, это должно сэкономить немало времени .... опция -m была доступна espl для сценария вроде этого ... ie sort -m file * | uniq -u – nsd

ответ

30

Прежде всего, вы не используете полную мощность cat. Цикл можно заменить на

cat data/* > dnsFull 

Предполагая, что файл изначально пуст.

Тогда есть все эти временные файлы, которые заставляют программы ждать жестких дисков (обычно самые медленные части в современных компьютерных системах). Использование трубопровода:

cat data/* | sort | uniq > dnsOut 

Это по-прежнему расточительно, так как только sort может делать то, что вы используете cat и uniq для; весь сценарий может быть заменен

sort -u data/* > dnsOut 

Если это еще не достаточно быстро, то понимают, что сортировка занимает O (п Л.Г. п) время, в то время как дедупликация может быть сделана в линейное время с Awk:

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

Очень хорошо сказал, спасибо. – drk

+5

Обратите внимание, что последний awk можно упростить до 'awk '! A [$ 0] ++' data/*' –

+1

Я удалил свой perl-ответ, потому что 350 * 75 МБ = более 26 ГБ - сортировка в памяти (например, awk) может вызвать слишком много обмена памятью. – jm666