Нет необходимости в нескольких процессах и трубах.awk
более чем способен справиться со всей работой (и будет работать на несколько порядков быстрее с большими файлами).С помощью awk
просто добавьте каждое из полей 2-NF
в виде строки и используйте его в качестве индекса для суммирования чисел в поле 1 в массиве.Затем в разделе END
просто выведите содержимое массива, например, предположив, что ваши данные хранятся в file
, вы можете сделать:
awk '{
for (i=2; i<=NF; i++)
str = str " " $i
a[str] += $1
str=""
}
END {
for (i in a) print a[i], i
}' file
Выше, первый цикл for
просто добавляетсявсе поля из 2-NF
в str
, a[str] += $1
суммируют значения в поле 1 в массив a
, используя str
в качестве индекса.Это гарантирует, что значения для похожих строк суммируются.В разделе END
вы просто зацикливаетесь на каждом элементе массива, выводя значение элемента (сумму), а затем индекс (оригинал str
для полей 2-NF
).
ПримерИспользуйте / Output
Просто возьмите то, что выше, выберите его, а затем вставьте его средней кнопкой мыши в командную строку в каталоге, где расположен ваш file
(измените имя file
к имени файла данных)
$ awk '{
> for (i=2; i<=NF; i++)
> str = str " " $i
> a[str] += $1
> str=""
> }
> END {
> for (i in a) print a[i], i
> }' file
30 take a test
37 cup of coffee
75 sign on the dotted
Если вы хотите, чтобы строки были отсортированы в другом порядке, просто добавьте | sort [options]
после имени файла, чтобы направить вывод в sort
.Например, для вывода в указанном порядке вы должны использовать | sort -k 2
, а результат будет:
37 cup of coffee
75 sign on the dotted
30 take a test
Сохранение исходного порядка строк
В соответствии сВаш комментарий относительно того, как сохранить исходный порядок строк текста, видимого во входном файле, вы можете сохранить второй массив, где строки хранятся в порядке их просмотра, используя последовательный индекс, чтобы сохранить их в порядке.Например, массив o
(массив заказов) используется ниже для хранения уникальной строки (поля 2-NF
), а переменная n
используется в качестве счетчика.Цикл над массивом используется для проверки того, содержит ли строка уже, и если это так, next
используется, чтобы избежать сохранения строки и перейти к следующей записи ввода.В END
цикл затем использует форму for (i = 0; i < n; i++)
для вывода информации из обоих массивов в том порядке, в котором строка была видна в исходном файле, например,
awk -v n=0 '{
for (i=2; i<=NF; i++)
str = str " " $i
a[str] += $1
for (i = 0; i < n; i++)
if (o[i] == str) {
str=""
next;
}
o[n++] = str;
str=""
}
END {
for (i = 0; i < n; i++) print a[o[i]], o[i]
}' file
Вывод
37 cup of coffee
75 sign on the dotted
30 take a test