LINUX.ORG.RU

Сортировка строк

 


0

2

Ребят, помогите пожалуйста. Имеется скрипт небольшой на bash, который извлекает из файлов емейлы. Хотелось бы сортировку сделать: убрать повторяющиеся строки и отсортировать по алфавиту. Моя же сортировка работает, когда файл небольшого размера :/. Я совсем не кодер, так что его скорее всего можно ещё и оптимизировать. :)

dir=/var/article/2014/$MM/$DD
echo "Ищем в директории $dir"
#Поиск директорий по имени файлов
find $dir -type f -name 'Unbenannt-[1-4].eml' | wc -l
find $dir -type f -name 'Unbenannt-[1-4].eml' > ~/emaildir.log

#Ищем по директориям файлов из файла emaildir.log адреса, вырезая лишнее
while read line
do
echo "$line"
grep -r 'To: "' $line |awk '{print $2}'| tr -d \" >> ~/email_2014.$MM.$DD
grep -r 'Final-recipient: RFC822;' $line |egrep -v '@gu.ru|@ru.ru' |awk '{print $3}' >> ~/email_2014.$MM.$DD
done < "emaildir.log"

sort -u ~/email_2014.$MM.$DD > ~/email_2014.$MM.$DD.s

#Тут должен быть заголовок вставлен, но тоже не работает
echo "Day $DD $MM 2014" | cat - ~/email_2014.$MM.$DD.s

Короче говоря, sort -u не справляется с большим объёмами. Он только лишь сортирует по алфавиту, но оставляет повторы емейлов.

хрень какая-то. комментарии не соответствуют действиям

поиск файлов find $dir -type f -name 'Unbenannt-[1-4].eml' > ~/emaildir.log

#Ищем по директориям файлов из файла emaildir.log адреса

в этом файле список файлов, а не директорий

Все лажа. Лучше бы сразу спросили все сделать за вас.

sdio ★★★★★ ()
Ответ на: комментарий от anonymous

Вы, оба, заголовок только прочитали?

sdio ★★★★★ ()

насколько много уникальных значений должно быть? в память влезет? если уников не много, то вместо

awk '{print $3}' 

сразу отсекать их:

awk '{ if (!x[$3]) { print $3; x[$3]=1 } }'

bl ★★★ ()
echo "Day $DD $MM 2014" > ~/email_2014.$MM.$DD.s
while read line
do
echo "$line"
grep -r 'To: "' $line |awk '{print $2}'| tr -d \" >> ~/email_2014.$MM.$DD
grep -r 'Final-recipient: RFC822;' $line |egrep -v '@gu.ru|@ru.ru' |awk '{print $3}' >> ~/email_2014.$MM.$DD
done < "emaildir.log" | sort -u > ~/email_2014.$MM.$DD.s
anonymous ()
Ответ на: комментарий от bl

Там ещё пару грепов в разных файлах. От разных файлов и получаются одинаковые в итоге емейлы. Но идея хорошая, возьму на заметку. Спасибо.

kcehna ()
Ответ на: комментарий от anonymous

head email_2014.07.15.s

/var/article/2014/07/15/389185/Unbenannt-3.eml /var/article/2014/07/15/389200/Unbenannt-3.eml

Нужны именно емейлы, а не директории сортировать :)

kcehna ()

Короче говоря, sort -u не справляется с большим объёмами. Он только лишь сортирует по алфавиту, но оставляет повторы емейлов.

Насколько большие объёмы то в гигабайтах? В /tmp достаточно места, сколько памяти (через ″-S″) разрешено использовать sort'у? И есть короткий пример листинга, где остаются повторы адресов, или это только на больших вылазит?

Да, и если вам нужно что-то писать в начало файла, то сначала пишите в пустой файл, а потом дописывайте туда вывод sort. А если ″Day $DD $MM 2014″ должен быть просто выведен на stdout, то делайте сначало ″echo″, а потом ″cat″ без всякого конвеера.

mky ★★★★★ ()
Ответ на: комментарий от mky

Насколько большие объёмы то в гигабайтах? В /tmp достаточно места, сколько памяти (через ″-S″) разрешено использовать sort'у? И есть короткий пример листинга, где остаются повторы адресов, или это только на больших вылазит?

Вот в этом уже вылазят повторы. Не такие уж и большие :|

# du -sh email_2014.07.15.s 
160K    email_2014.07.15.s
# du -sh email_2014.07.15
188K    email_2014.07.15
получается нужно sort с параметром -S, только вот сколько ставить, как зависит?

Да, и если вам нужно что-то писать в начало файла, то сначала пишите в пустой файл, а потом дописывайте туда вывод sort. А если ″Day $DD $MM 2014″ должен быть просто выведен на stdout, то делайте сначало ″echo″, а потом ″cat″ без всякого конвеера.

В итоге сделала седом, иначе он сортирует и дату, если в пустой файл делать.

sed -i "1 i Day $DD $MM 2014" ~/email_2014.$MM.$DD.s

kcehna ()
Ответ на: комментарий от kcehna

ну чего ты в самом деле, я же идею показал

echo "Day $DD $MM 2014" > ~/email_2014.$MM.$DD.s
while read line
do
# echo "$line"
grep -r 'To: "' $line |awk '{print $2}'| tr -d \"
grep -r 'Final-recipient: RFC822;' $line |egrep -v '@gu.ru|@ru.ru' |awk '{print $3}'
done < "emaildir.log" | sort -u > ~/email_2014.$MM.$DD.s

anonymous ()
Ответ на: комментарий от anonymous
- done < "emaildir.log" | sort -u > ~/email_2014.$MM.$DD.s
+ done < "emaildir.log" | sort -u >> ~/email_2014.$MM.$DD.s
anonymous ()

Чушь собачья, спокойно гоняю sort -u на файлах с миллиардом строк.

xtraeft ★★☆☆ ()
Ответ на: комментарий от kcehna

В итоге сделала седом, иначе он сортирует и дату, если в пустой файл делать.

Чего? Как он дату может сортировать, если она в выходном файле? Делаем:

echo "Day $DD $MM 2014" > ~/email_2014.$MM.$DD.s
sort -u ~/email_2014.$MM.$DD >> ~/email_2014.$MM.$DD.s

А ″sed -i″ создаёт временный файл, туда пишет результат и потом перемещает этот временный файл на место основного. Совершенно не нужные в случае вашего скрипта траты ресурсов.

вылазят повторы.

Повторы идут в email_2014.07.15.s подряд? Команда uniq -d email_2014.07.15.s выводит эти повторы? Если выводит, то, наверное, нужно писать багрепорт на ″sort″. Иначе смотреть, чем эти повторы, всё таки, отличаются (допустим пробелом перед переводом строки).

mky ★★★★★ ()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.