Удаление повторяющихся строк и вычисление суммы чисел слева

Программирование на sh, быть может немного про альтернативные языки
Правила форума
Убедительная просьба юзать теги [code] при оформлении листингов.
Сообщения не оформленные должным образом имеют все шансы быть незамеченными.
Marcello
ефрейтор
Сообщения: 64
Зарегистрирован: 2011-07-09 11:59:08

Удаление повторяющихся строк и вычисление суммы чисел слева

Непрочитанное сообщение Marcello » 2011-07-09 12:05:46

всем привет. например есть такой файл

7 str1
9 str2
20 str3
26 str4
10 str3
15 str5
...

необходимо удалить повторяющиеся строки, которые находится на расстоянии 1 пробела от числа, и сложить числа слева, чтобы в итоге получилась такая картина:

7 str1
9 str2
30 str3
26 str4
15 str5
...

есть идеи как это шустренько сделать? :)

Хостинговая компания Host-Food.ru
Хостинг HostFood.ru
 

Услуги хостинговой компании Host-Food.ru

Хостинг HostFood.ru

Тарифы на хостинг в России, от 12 рублей: https://www.host-food.ru/tariffs/hosting/
Тарифы на виртуальные сервера (VPS/VDS/KVM) в РФ, от 189 руб.: https://www.host-food.ru/tariffs/virtualny-server-vps/
Выделенные сервера, Россия, Москва, от 2000 рублей (HP Proliant G5, Intel Xeon E5430 (2.66GHz, Quad-Core, 12Mb), 8Gb RAM, 2x300Gb SAS HDD, P400i, 512Mb, BBU):
https://www.host-food.ru/tariffs/vydelennyi-server-ds/
Недорогие домены в популярных зонах: https://www.host-food.ru/domains/

rmn
старшина
Сообщения: 427
Зарегистрирован: 2008-10-03 18:52:02

Re: Удаление повторяющихся строк и вычисление суммы чисел сл

Непрочитанное сообщение rmn » 2011-07-09 12:44:03

Код: Выделить всё

remcomp% cat file.txt 
7 str1
9 str2
20 str3
26 str4
10 str3
15 str5
remcomp% cat script.sh 
#!/bin/sh

txt1=""
sum=""

cat file.txt | awk '{print $2,$1}' | sort |
(
        while read txt2 num
        do
                if [ -z "${sum}" ]; then
                        sum="$num"
                        txt1="$txt2"
                        continue
                fi

                if [ "${txt1}" = "${txt2}" ]; then
                        sum="`expr $sum + $num`"
                else
                        echo $sum $txt1
                        txt1="$txt2"
                        sum="$num"
                fi
        done

        if [ "${txt1}" != "${txt2}" ]; then
                echo $sum $txt1
        fi
)

remcomp% ./script.sh 
7 str1
9 str2
30 str3
26 str4
15 str5

Marcello
ефрейтор
Сообщения: 64
Зарегистрирован: 2011-07-09 11:59:08

Re: Удаление повторяющихся строк и вычисление суммы чисел сл

Непрочитанное сообщение Marcello » 2011-07-09 13:18:00

хм, интересно, значит сначала преобразуем в

str1 7
str2 9
str3 20
str4 26
str3 10
str5 15

сортируем, получаем

str1 7
str2 9
str3 10
str3 20
str4 26
str5 15

а вот не совсем понятно что у нас здесь

Код: Выделить всё

while read txt2 num
        do
                if [ -z "${sum}" ]; then
                        sum="$num"
                        txt1="$txt2"
                        continue
                fi

                if [ "${txt1}" = "${txt2}" ]; then
                        sum="`expr $sum + $num`"
                else
                        echo $sum $txt1
                        txt1="$txt2"
                        sum="$num"
                fi
        done
в общем то ясно что идет последовательное чтение строк с файла, но вот что значит if [ -z ? можно пожалуйста линк где про sh if подробней, комментариев можно?

Marcello
ефрейтор
Сообщения: 64
Зарегистрирован: 2011-07-09 11:59:08

Re: Удаление повторяющихся строк и вычисление суммы чисел сл

Непрочитанное сообщение Marcello » 2011-07-09 13:23:59

такс, кое-что уже нашел http://www.opennet.ru/man.shtml?topic=t ... &russian=0 (man test)
Значит я так понимаю здесь if [ -z "${sum}" ]; then проверяется, не нулевой ли длины строка в sum

Marcello
ефрейтор
Сообщения: 64
Зарегистрирован: 2011-07-09 11:59:08

Re: Удаление повторяющихся строк и вычисление суммы чисел сл

Непрочитанное сообщение Marcello » 2011-07-09 13:42:26

если нулевая, мы имеем дело с первой строкой, просто присваиваем переменные и переходим к следующей итерации цикла.

если txt1 = txt2 (соседи), тогда мы вычисляем сумму и переходим к следующей строке, если и она встречается дальше, делаем то же самое, пока нам не попадется
строка, которая не будет совпадать, тогда мы ее выводим, присваиваем txt1 значение текущей строки (в след. итерации уже соответственно предыдущей)
и присваиваем так же новое значение для sum

ну и наконец-то в конце

if [ "${txt1}" != "${txt2}" ]; then
echo $sum $txt1
fi

проверяет последнюю строку файла, поскольку нету следующей строки, с которой она может сравниться, поэтому она обрабатывается отдельно

Ну что, все верно я понял? :)

Аватара пользователя
ProFTP
подполковник
Сообщения: 3388
Зарегистрирован: 2008-04-13 1:50:04
Откуда: %&й
Контактная информация:

Re: Удаление повторяющихся строк и вычисление суммы чисел сл

Непрочитанное сообщение ProFTP » 2011-07-09 13:46:16

нужно на shell или можно на чем угодно? :)

Код: Выделить всё

perl -ne ' while ( $_ =~ /(.+)\s(.+)\n/smg ) {  if (exists $h->{$2} ) { $h->{$2}=$1+$h->{$2} } else { $h->{$2}=$1 }  }  END {  print $h->{$_}." ".$_."\n"  for keys %$h }' te.txt

Код: Выделить всё

9 str2
26 str4
7 str1
15 str5
30 str3
Pеrl FAQ
perl -e 'print join"",map $$_[rand@$_],([0..9,'a'..'z','A'..'Z'])x30'
ИзображениеИзображение

Marcello
ефрейтор
Сообщения: 64
Зарегистрирован: 2011-07-09 11:59:08

Re: Удаление повторяющихся строк и вычисление суммы чисел сл

Непрочитанное сообщение Marcello » 2011-07-09 13:51:14

ProFTP, спасибо, но лучше на шелле, надеюсь быстрее на нем работать будет.

заменяем file.txt на $1 и теперь можем передавать параметром имя файла, который будет анализироваться, лепота.