ошибка в скрипте bash - PullRequest
       3

ошибка в скрипте bash

0 голосов
/ 02 апреля 2011

У меня есть входные файлы этого формата

real 0.00  
user 0.00  
sys 0.00  
real 0.00  
user 0.00  
sys 0.00  
real 0.00  
user 0.00  
sys 0.00  

Я пишу bash-скрипт для получения среднего значения «реальных» значений. Это сценарий, который я написал

#! /bin/sh

# FILES=/home/myfiles

 for f in $FILES
 do
        echo " Processing $f file.."
        sum=0;
        grep real $f  | while read LINE; do
                value=$(sed "s/[^0-9]//g")
                #value=`awk "^[0-9]"`
                echo $value
                $sum+=$value
        done
        #average=$sum/10;
        #echo $average
 done

Но я получаю сообщение об ошибке в этом stmt

$sum+=$value

Есть решения, плз?

Ответы [ 4 ]

2 голосов
/ 02 апреля 2011

bash не поддерживает арифметику с плавающей запятой. Он поддерживает только целое число. Если вам все равно, как получить результат, awk лучше подготовлен для этого:

awk '/real/ {sum += $2} END {print sum}' files*

В / real / говорится "ищите эти строки со словом real", тогда {sum + = $ 2} означает добавление второго поля к sum По умолчанию переменная типа sum будет начинаться как пустая или ноль зависит от контекста. Наконец, шаблон END говорит: «после обработки всех файлов выведите сумму».

2 голосов
/ 02 апреля 2011

Лучше использовать awk или какой-либо язык программирования, который выполняет обработку файлов, а также математические вычисления в одном.Bash не поддерживает математические операции с плавающей точкой.Проблема с вашим скриптом в том, что вы вызываете внешнюю команду sed для каждой найденной вами «реальной» строки.Это хит производительности.

awk '/real/{s+=$2;c++}END{print "average is: " s/c}' file
2 голосов
/ 02 апреля 2011

Используйте это:

sum+=$value

В противном случае вы бы сказали "0 + = $ value"

Также вы можете сделать:

grep real $f  | while read LINE value; do

Это избавит от необходимости sed / awk.

0 голосов
/ 02 апреля 2011

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

  • Значения сбрасываются в массив (каналы, из-за которых математика возникала в подоболочке), результаты не смогут перейти в «основную» оболочку
  • Добавлена ​​дополнительная обработка в выражении sed для удаления начальных нулей (но убедитесь, что есть хотя бы одна цифра)
  • Я не понял, почему для вычисления среднего вы делите на 10, поэтому я использую фактическое количество элементов в массиве
  • наконец, предполагая, что вы хотите получить среднее значение в той же единице измерения, что и для ввода - я печатаю с printf результат деления на 100.

-

#! /bin/sh

# FILES=/home/myfiles
FILES=a
 for f in $FILES
 do
        echo " Processing $f file.."
        values=($(grep real ${f} | sed -e "s/[^0-9]//g" -e "s/^0*//" -e "s/^$/0/"))
        sum=0;
        for value in ${values[@]}; do
          echo $value
          ((sum+=value))
        done
        average=$((sum/${#values[@]}));
        printf "AVG: %d.%02d\n" $((average/100)) $((average%100))
 done
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...