Вот быстрый 100% скрипт bash, который сделает эту работу:
a=()
while read _ n; do
[[ -n $n ]] && ((++a[n]))
done < datafile.txt
c=0
for i in ${!a[@]}; do
echo "$((c+=a[i])) $i"
done
Если вам нужен скрипт, который вы можете вызвать из командной строки:
#!/bin/bash
a=()
while read _ n; do
[[ -n $n ]] && ((++a[n]))
done < "$1"
c=0
for i in ${!a[@]}; do
echo "$((c+=a[i])) $i"
done
Или, если вы предпочитаете однострочку, чтобы произвести впечатление на вашу бабушку:
a=(); while read _ n; do [[ -n $n ]] && ((++a[n])); done < datafile.txt; c=0; for i in ${!a[@]}; do echo "$((c+=a[i])) $i"; done
Он работает примерно за 2-3 секунды на двухъядерном процессоре Pentium с частотой 2,6 ГГц в файле с 100000 строк.
редактировать
Пояснения:
Первый цикл:
- Мы инициализируем,
a
чтобы быть пустым массивом:a=()
- Мы читаем файл
datafile.txt
построчно. В каждой строке два поля, только второе добавляется в имена переменныхn
- Если
n
не пусто (это тест, [[ -n $n ]]
мы увеличиваем значение n
ключа -th массива a
; это то, что ((++a[n]))
делает строка . ((...))
Это арифметический контекст bash.
- После прочтения всех файлов у нас есть массив
a
, и k
поле -th - это количество автономных систем, степень которых равна k
.
Тогда второй цикл:
- Перед циклом переменная
c
устанавливается в 0.
for i in ${!a[@]}; do
будет перебирать все ключи массива a
.
$((c+=a[i]))
добавит значение a[i]
к c
и расширит это значение. Это значение echo
редактируется с i
добавлением значения ключа .
Надеюсь это поможет!