Вот мой код; Я хочу сравнить $COUNTER с разными значениями несколько раз.

if [ "$COUNTER" = "5" ]; then

Все в порядке, но я хочу, чтобы это делалось для динамических периодов времени, таких как 5,10,15,20 и т. д.

5
steve 11 Фев 2018 в 19:03
Итак, вы хотите проверить, является ли $COUNTER кратным числу 5?
 – 
Arkadiusz Drabczyk
11 Фев 2018 в 17:48
Да вроде 5, 10, 15 или 200, 400, 600 что-то в этом роде.
 – 
Mehran Goudarzi
11 Фев 2018 в 17:49
Вы не ответили на мой вопрос. Как насчет 30 - это тоже кратно 5, подойдет?
 – 
Arkadiusz Drabczyk
11 Фев 2018 в 17:50
Вы имеете в виду, что хотите, чтобы часть «5» была переменной, а не просто «5», чтобы вы сравнивали $COUNTER с другой переменной, или вы хотите увидеть, является ли $COUNTER кратным пяти?
 – 
Jeff Schaller
11 Фев 2018 в 18:00
1
Ваш заголовок наводит меня на мысль, что вы хотите спросить, является ли $COUNTER одним из набора значений: «это 5, или 10, или 15, или 20, или 200, или…»? Если это так, что это за набор значений? Как они определяются?
 – 
Jeff Schaller
11 Фев 2018 в 18:06

3 ответа

Лучший ответ

Заключение различных комментариев, похоже, состоит в том, что самый простой ответ на исходный вопрос

if ! (( $COUNTER % 5 )) ; then
4
steve 11 Фев 2018 в 19:08
Да, если конкретная рассматриваемая оболочка понимает этот синтаксис. Bash и несколько других основных оболочек делают это.
 – 
Kusalananda
11 Фев 2018 в 19:43
В этом случае что-то вроде if (( (k/5)*5 == k )) или даже if [ $k -ne `expr $k / 5 \* 5` ]
 – 
roaima
12 Фев 2018 в 18:30
Проблема заключается в двойных скобках, а не в операторе модуля.
 – 
Kusalananda
12 Фев 2018 в 18:35

Вы можете сделать это с помощью арифметического оператора по модулю:

#!/bin/sh

counter="$1"
remainder=$(( counter % 5 ))
echo "Counter is $counter"
if [ "$remainder" -eq 0 ]; then
    echo 'its a multiple of 5'
else
    echo 'its not a multiple of 5'
fi

В использовании:

$ ./modulo.sh 10
Counter is 10
its a multiple of 5
$ ./modulo.sh 12
Counter is 12
its not a multiple of 5
$ ./modulo.sh 300
Counter is 300
its a multiple of 5

Я также написал цикл, который может быть тем, что вы ищете? Это будет перебирать все числа от 1 до 600 и проверять, кратны ли они 5:

loop.sh

#!/bin/sh
i=1
while [ "$i" -le 600 ]; do
        remainder=$(( i % 5 ))
        [ "$remainder" -eq 0 ] && echo "$i is a multiple of 5"
        i=$(( i + 1 ))
done

вывод (сокращенный)

$ ./loop.sh
5 is a multiple of 5
10 is a multiple of 5
15 is a multiple of 5
20 is a multiple of 5
25 is a multiple of 5
30 is a multiple of 5
...
555 is a multiple of 5
560 is a multiple of 5
565 is a multiple of 5
570 is a multiple of 5
575 is a multiple of 5
580 is a multiple of 5
585 is a multiple of 5
590 is a multiple of 5
595 is a multiple of 5
600 is a multiple of 5
3
jesse_b 11 Фев 2018 в 18:54
1
200, 400 и 600 тоже кратны 5...
 – 
Jeff Schaller
11 Фев 2018 в 17:58
2
В bash нельзя ли упростить это до if ((counter%5 == 0)); then ... ?
 – 
steeldriver
11 Фев 2018 в 18:06
1
Или if ! ((counter%5)); then...
 – 
don_crissti
11 Фев 2018 в 18:13
1
Я сделал свой ответ в sh, потому что op использует [, а не [[
 – 
jesse_b
11 Фев 2018 в 18:13
2
В арифметическом контексте (внутри $(( ... ))) кавычки и $ не нужны. Я думал, ты говоришь о тесте [ ... ].
 – 
Kusalananda
11 Фев 2018 в 18:18

Отвечая на вопрос точно, как он написан в настоящее время, не обращая внимания на заголовок (который был отредактирован).

Чтобы сравнить целое число в переменной с рядом других целочисленных значений, где другие значения определяются заранее (неясно, что на самом деле означает «динамически» в вопросе):

case "$value" in
    5|10|15|200|400|600)
        echo 'The value is one of those numbers' ;;
    *)
        echo 'The value is not one of those numbers'
esac

Это также может быть сделано в цикле, конечно,

for i in 5 10 15 200 400 600; do
    if [ "$value" -eq "$i" ]; then
        echo 'The value is one of those numbers'
        break
    fi
done

Но это усложняет обработку случая, когда $value не находится среди заданных чисел без использования какого-либо флага:

found=0
for i in 5 10 15 200 400 600; do
    if [ "$value" -eq "$i" ]; then
        echo 'The value is one of those numbers'
        found=1
        break
    fi
done

if [ "$found" -eq 0 ]; then
    echo 'The value is not one of those numbers'
fi

Или, почище,

found=0
for i in 5 10 15 200 400 600; do
    if [ "$value" -eq "$i" ]; then
        found=1
        break
    fi
done

if [ "$found" -eq 1 ]; then
    echo 'The value is one of those numbers'
else
    echo 'The value is not one of those numbers'
fi

Лично я бы выбрал реализацию case ... esac.

2
Kusalananda 12 Фев 2018 в 18:10