Я пытаюсь создать сценарий bash, который читает целые числа из файла (одно число в строке, имя файла передается в качестве аргумента сценария), находит максимум, минимум и сумму. Однако у меня проблема с той частью, где я сравниваю переменные. Код ниже (здесь я пропустил часть, которая проверяет, существует ли файл или он пуст):
#!/bin/bash
min=`cat "$1" | head -n 1`
max=$min
sum=0
lw=`cat "$1" | wc -l`
while [ $lw -gt 0 ];
do
num=`cat "$1" | tail -n $lw | head -n 1`
if [ "$num" -gt "$max" ]
then
max=$num
elif [ "$num" -lt "$min" ]
then
min=$num
fi
sum=$[sum+num]
lw=$[$lw-1]
done
echo "Maximum: $max"
echo "Minimum: $min"
echo "Sum: $sum"
С этим кодом я получаю ошибки в строках 13 и 16: [: : ожидается целочисленное выражение
Если я изменю часть сравнения внутри цикла while на:
if [ $num -gt $max ]
then
max=$num
elif [ $num -lt $min ]
then
min=$num
fi
Я получаю ошибки:
строка 13: [: -gt: ожидается унарный оператор
строка 16: [: -lt: ожидается унарный оператор
Что я делаю не так? Я новичок в bash, поэтому буду очень признателен за любую помощь.
Данные, которые я использовал для тестирования:
5
6
8
2
3
5
9
10
Я предполагаю, что выражение
num=`cat "$1" | tail -n $lw | head -n 1`
присваивает num некоторое значение, которое не является числом ни на одной из итераций. Я бы предложил добавить echo "$num"
в предыдущей строке, чтобы проверить это предположение.
Возможно, ваш входной файл содержит окончания строк DOS или другое неправильное форматирование. Ваш код должен работать для правильно сформированных входных данных.
Однако правильный способ зацикливания строк в файле:
#!/bin/bash
min=$(sed 1q "$1")
max=$min
sum=0
while read -r num; do
if [ "$num" -gt "$max" ]
then
max=$num
elif [ "$num" -lt "$min" ]
then
min=$num
fi
((sum+=num))
done<"$1"
echo "Maximum: $max"
echo "Minimum: $min"
echo "Sum: $sum"
Обратите также внимание на то, что обратные кавычки и $[[...]]]
используют синтаксис, который уже десятилетиями устаревает.
Еще одно: вместо чтения строк с помощью cat | tail | head
проще читать файл построчно, используя следующий синтаксис.
while IFS= read -r line
do
echo "$line"
done < "$input"
Это прочитает содержимое файла input
в переменную line
.
См. здесь объяснения о IFS=
и -r
https://www.cyberciti.biz/faq/unix-howto-read-line-by-line-from-file/ - оба они не очень нужны в вашем случае
Привет, ты прав. Я не заметил, что у меня есть пустая строка в данных тестирования.