Bash сравнивает переменные, которые являются целыми числами, с -gt -lt

Я пытаюсь создать сценарий 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

Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Коллекции в Laravel более простым способом
Коллекции в Laravel более простым способом
Привет, читатели, сегодня мы узнаем о коллекциях. В Laravel коллекции - это способ манипулировать массивами и играть с массивами данных. Благодаря...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
Массив зависимостей в React
Массив зависимостей в React
Все о массиве Dependency и его связи с useEffect.
Toor - Ангулярный шаблон для бронирования путешествий
Toor - Ангулярный шаблон для бронирования путешествий
Toor - Travel Booking Angular Template один из лучших Travel & Tour booking template in the world. 30+ валидированных HTML5 страниц, которые помогут...
1
0
129
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Я предполагаю, что выражение

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"

Обратите также внимание на то, что обратные кавычки и $[[...]]] используют синтаксис, который уже десятилетиями устаревает.

Привет, ты прав. Я не заметил, что у меня есть пустая строка в данных тестирования.

Ameia 20.12.2020 13:05

Еще одно: вместо чтения строк с помощью cat | tail | head проще читать файл построчно, используя следующий синтаксис.

while IFS= read -r line
do
  echo "$line"
done < "$input"

Это прочитает содержимое файла input в переменную line.

См. здесь объяснения о IFS= и -rhttps://www.cyberciti.biz/faq/unix-howto-read-line-by-line-from-file/ - оба они не очень нужны в вашем случае

Другие вопросы по теме