Расширение *
выполняется оболочкой, выполняющей команду.
По умолчанию оболочки пропускают точечные файлы (скрытые файлы).
Самым простым и переносимым решением (не zsh) было бы использование:
$ grep Hello * .[!.]*
Второй глобус . [!.] *
эквивалентен . [^.] *
и необходим для некоторых оболочек (используйте форму ^
для zsh, csh и tcsh или .
. ~.] *
для RC
/ es
).
Добавляет точечные файлы в список для grep.
Если необходимо обработать имена файлов, отличные от ..
, начинающиеся с 2 точек, добавьте третью глобус Справочная страница из UNIX FAQ :
$ grep Hello * .[!.]* ..?*
Если вы хотите посмотрите, что происходит, выполните:
echo grep Hello * .[!.]* ..?*
И проверьте, почему это не совсем работает: echo grep Hello *. *
В ksh или bash с активным extglob (по умолчанию включено при интерактивном использовании для bash):
grep Hello .!(.|) *
Или только для bash, просто используйте dotglob:
shopt -s dotglob; grep Hello *
grep Hello *(D.)
Вы не сказали, что числа передаются сценарию в стандартном вводе.
Для этого будет работать этот код:
#!/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
Поскольку вам нужны вычисления с плавающей запятой, вы все равно будете использовать 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
Вы включали первое число в сумму и написали неверное условие:
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
Простое решение POSIX:
average() { printf '%s\n' 'scale=2' "($*)/$#" | tr ' ' + | bc;}
Затем запустите его так:
average 4 1 2 9 8
Выход:4.80