Вычислить среднее значение с помощью аргумента командной строки

Расширение * выполняется оболочкой, выполняющей команду.
По умолчанию оболочки пропускают точечные файлы (скрытые файлы).

Самым простым и переносимым решением (не zsh) было бы использование:

$ grep Hello * .[!.]* 

Второй глобус . [!.] * эквивалентен . [^.] * и необходим для некоторых оболочек (используйте форму ^ для zsh, csh и tcsh или . . ~.] * для RC / es ).
Добавляет точечные файлы в список для grep.

Если необходимо обработать имена файлов, отличные от .. , начинающиеся с 2 точек, добавьте третью глобус Справочная страница из UNIX FAQ :

$ grep Hello * .[!.]* ..?*

Если вы хотите посмотрите, что происходит, выполните:

echo grep Hello * .[!.]* ..?*

И проверьте, почему это не совсем работает: echo grep Hello *. *


ksh | bash

В ksh или bash с активным extglob (по умолчанию включено при интерактивном использовании для bash):

grep Hello .!(.|) *

Или только для bash, просто используйте dotglob:

shopt -s dotglob; grep Hello *

zsh

grep Hello *(D.)

0
07.02.2016, 21:46
4 ответа

Вы не сказали, что числа передаются сценарию в стандартном вводе.

Для этого будет работать этот код:

#!/bin/bash
readarray -t x
count="${x[0]}" ; unset x[0]
for y in ${x[@]}; do (( sum+=y )); done
a="$(echo "scale=8; $sum/$count" | bc)"
LC_ALL=C printf '%0.3f\n' "$a"

Протестируйте его следующим образом:

$ printf '%s\n' 4 1 2 9 8 | ./script
5.000
$ printf '%s\n' 6 1 2 9 8 13 25 | ./script
9.667
0
29.04.2021, 00:18

Поскольку вам нужны вычисления с плавающей запятой, вы все равно будете использовать bc или awk. Почему бы не использовать Awk для решения всей проблемы? Вот решение только для Awk, я использовал n для числителя и d для знаменателя:

$ printf "4\n1\n2\n9\n8\n" | awk '{if (NR == 1) {d = $0}; if (NR != 1) {n += $0}} END{printf "%.03f\n", n/(d*1.0)}'
5.000
2
29.04.2021, 00:18

Вы включали первое число в сумму и написали неверное условие:

if [count -eq "1"]

вместо

if [$ count -eq 1]

Оператор $ позволяет получить доступ к переменной, и вы использовали 1 как строку вместо целого числа.

#!/bin/bash
read n
p=$n
sum=0
count=1
while [ $count -le $p ]
do
    read n
    x=$n
    count=$(($count + 1))
    sum=$(($sum + $x))
done
result=`echo $sum $p | awk '{printf "%.3f", $1/$2 }'`
echo $result
0
29.04.2021, 00:18

Простое решение POSIX:

average() { printf '%s\n' 'scale=2' "($*)/$#" | tr ' ' + | bc;}

Затем запустите его так:

average 4 1 2 9 8

Выход:4.80

0
29.04.2021, 00:18

Теги

Похожие вопросы