У меня есть файл с несколькими тегами и номером рядом с ним, например
<Overall>4
other <tags> and data
<Overall>2
other <tags> and data
<Overall>3
Как мне выполнить поиск по файлу и подсчитать все числа рядом с общим тегом? А затем разделить число на количество общих тегов, чтобы получить общее среднее значение.
Так, например, в приведенном выше коде среднее значение будет равно 3.
Затем пройдитесь по всем файлам в текущем каталоге и выведите общее среднее значение для каждого файла.
решение1
Использование awk (предполагая, что все, что есть в общих строках, это это и число)
awk 'x+=sub(/<Overall>/,""){y+=$0}END{print "AVG:",y/x}' file
x увеличивается для каждой успешной подпрограммы с <Overall>
пустыми строками. Это означает, что он увеличивается только на строках, содержащих <Overall>
.
Последующий блок добавляет к общей сумме число, оставшееся на линии.
END
выполняется в конце программы.
В конечном блоке выводится среднее значение.
EDIT:для множества файлов
awk 'x+=sub(/<Overall>/,""){y+=$0}END{print FILENAME,"AVG:",y/x}' LISTOFFILES
решение2
С perl
:
perl -lne 'for (/<Overall>([\d.eE+-]+)/g) {$n++; $sum += $1}
END{print $sum/$n if $n}'
Преимущество этого метода заключается в возможности обработки более одного <Overall>
тега на строку. [\d.eE+-]+
Это грубый сопоставитель для десятичных чисел с плавающей точкой (допускающий такие значения, как 12, 1.2, -1E+20 (хотя также и то, что не является допустимыми числами)).
решение3
Вот грубый способ на awk:
awk '/^<Overall>/ {
sub("<Overall>", "");
sum += $1;
lines++;
}
END { print sum / lines}'
tags ### this is your input file
решение4
Вот решение с использованием нескольких полезных утилит:
grep "^<Overall>\d\+" file | cut -c 10 | paste -s -d + - | bc
- Найдите в файле строки, начинающиеся с «<Overkill>», за которыми следует строка цифр (т. е. число).
- Вырежьте цифру из оставшейся части строки.
- Объедините все строки, поставив между ними символ «+».
- Передайте результат в
bc
, который вычислит сумму