Страница 1 из 1

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

Добавлено: 2011-07-09 12:05:46
Marcello
всем привет. например есть такой файл

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

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

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

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

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

Добавлено: 2011-07-09 12:44:03
rmn

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

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

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

Добавлено: 2011-07-09 13:18:00
Marcello
хм, интересно, значит сначала преобразуем в

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 подробней, комментариев можно?

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

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

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

Добавлено: 2011-07-09 13:42:26
Marcello
если нулевая, мы имеем дело с первой строкой, просто присваиваем переменные и переходим к следующей итерации цикла.

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

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

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

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

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

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

Добавлено: 2011-07-09 13:46:16
ProFTP
нужно на 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

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

Добавлено: 2011-07-09 13:51:14
Marcello
ProFTP, спасибо, но лучше на шелле, надеюсь быстрее на нем работать будет.

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