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

Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
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/ - оба они не очень нужны в вашем случае

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