Добавление чисел из результата grep


23

Я запускаю следующую команду:

grep -o "[0-9] errors" verification_report_3.txt | awk '{print $1}'

и я получаю следующий результат:

1
4
0
8

Я хотел бы добавить каждое из чисел до переменной счетчика. Есть ли волшебный лайнер, который кто-то может мне помочь построить?

Ответы:


32
grep -o "[0-9] errors" verification_report_3.txt | awk '{ SUM += $1} END { print SUM }'

Это не печатает список, но печатает сумму. Если вы хотите и список, и сумму, вы можете сделать:

grep -o "[0-9] errors" verification_report_3.txt | awk '{ SUM += $1; print $1} END { print SUM }'

Шон - спасибо за ответ. Как вернуть итоговое значение обратно в bash-скрипт из awk?
Амир Афганский

2
@Amir Вы можете использовать первый, как этот. variable=$(grep -o "[0-9] errors" verification_report_3.txt | awk '{ SUM += $1} END { print SUM }')Это помещает вывод команды (которая является только значением суммы) в переменную с именемvariable
Shawn J. Goff

3
@ Амир Афгани Также, вы можете изменить свой grep на "[0-9]\+ errors". Это будет соответствовать, если у вас есть строка, сообщающая> 9 ошибок.
Шон Дж. Гофф

Да, вау, я не могу поверить, что я пропустил это. Спасибо.
Амир Афганский

Шон, результат, похоже, не суммирует мои результаты. Выглядит это так: Всего ошибок = + 259 + 7581 + 8852 + 2014 + 3189 ++ 13572 + 11438 +++ 6 + 4172 +
Амир Афгани


6

Вы, кажется, используете систему GNU , поэтому, если доступна поддержка регулярных выражений Perl , вы можете написать что-то вроде этого:

grep -Po '[0-9]+(?=\s+errors)' infile | 
  paste -sd+ | 
    bc

PS Я изменил регулярное выражение (добавил + квантификатор), чтобы разрешить числа> 9.

PS В качестве альтернативы достаточно awk (при условии, что GNU awk ):

awk 'END { print s }
/[0-9]+[[:space:]]+errors/ { 
  s += $1 
  }' infile

первый для меня просто печатает то, что уже ушло в трубу ...
Xerus

3

Попробуйте передать вывод из вашего grep в

awk 'BEGIN {total=0;}{total+=$1;}END {print "Total: ",total}'

2

Я использую это:

$ echo $(cat file | sed 's/$/+/') 0 | bc

Это не эффективно для больших списков, но для большинства моих случаев использования это хорошо. Я обычно использую функцию оболочки для автоматизации процесса, поэтому мне нужно только указать имя файла:

## cheezy summation
##   call from .bashrc
##
getsum () { echo $(cat $1 | sed 's/$/+/') 0 | bc; }
gethsum () { echo $(cat $1 | sed 's/[gG]/*1000M/' | sed 's/[mM]/*1000K/' | sed 's/[kK]/*1000/' | sed 's/$/+/') 0 | bc; }
gethexsum () { echo ibase=16 $(cat $1 | sed 's/$/+/') 0 | bc; }

Вы всегда можете заменить маркер конца строки определенным разделителем элементов или классом символов, если ваши данные разделены другим способом.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.