Как добавить строку к числу

Как добавить строку к числу

Недавно я пытался создать скрипт, который может преобразовывать двоичное число в десятичное. Вот что у меня получилось:

#!/bin/bash

echo "Specify no of digits"
read digits

if [[ $digits == 1 ]]; then
        echo "Enter 1 st digit"
        read 1
elif [[ $digits == 2 ]]; then
        echo "Enter 1 st digit"
        read 1
        echo "Enter 2 nd digit"
        read 2
elif [[ $digits == 3 ]]; then
        echo "Enter 1 st digit"
        read 1
        echo "Enter 2 nd digit"
        read 2
        echo "Enter 3 rd digit"
        read 3
elif [[ $digits > 3 ]]; then
        echo "Enter 1 st digit"
        read 1
        echo "Enter 2 nd digit"
        read 2
        echo "Enter 3 rd digit"
        read 3
        for digitno in {4..$digits};
        do
                echo "Enter $digitno th digit"
                read $digitno
                ($nodigits++)
        done
echo "$4"
else
        echo "Please enter a valid no of digits. Type './binary_decoder.sh'"
        exit 1
fi

Я знаю, что это довольно длинный сценарий. Но, пожалуйста, постарайтесь уделить время изучению этого сценария.

Если вы посмотрите на любую из readстрок внутри условного оператора if, вы увидите, что переменные, которым readоператоры присваивают числа, сами являются числами. С синтаксисом Bash это не сработает. Я хочу, чтобы переменные были такими, как n1, n2, n3, n4... и так далее. Но если вы посмотрите внутрь оператора elif [[ $digits > 3 ]]; then, вы увидите, что есть цикл for, который позволяет декодировать бесконечное количество цифр. Теперь я не знаю способа добавить строку nк числу в переменной $digitno. Но мне было интересно, может ли кто-нибудь из вас разобраться, как добавить строку nк $digitnoпеременной.

Любая помощь будет оценена по достоинству.

решение1

Вы можете добавить строку к числу, используя простую конкатенацию:

$ i=3
$ echo n$i
n3

Однако это не очень помогает в достижении вашей настоящей цели, которая, по-видимому, заключается в том,как назначить неопределенное количество пользовательских вводов индексированным переменным.

Как вы уже обнаружили, в команде нельзя использовать переменные с именами , 1и т. д . Помимо того, что имена переменных bash должны быть как минимум23readначинатьс буквенным символом или подчеркиванием, расширения $1, $2, $3и т. д. зарезервированы для оболочкипозиционные параметры.

Если вы действительно хотите использовать $1... $nв своем скрипте, вы можете сделать это с помощью setвстроенной оболочки. Обратите внимание, что в то время как POSIX требует поддержки только параметров до $9, bash поддерживает произвольное число (хотя для индексов выше 9 вам нужно будет использовать фигурные скобки, чтобы устранить неоднозначность между, например, ${10}как 10 позиционный параметр и $10как конкатенация $1с литералом 0). Например:

#!/bin/bash

set --
while : ; do
  read -n1
  case $REPLY in
    [01]) set -- "$@" "$REPLY"
    ;;
    *) break
    ;;
  esac
done

for ((i=1; i<=$#; ++i)); do
  printf 'Digit #%d = %d\n' "$i"  "${!i}"
done

Пользователь вводит последовательность 0символов 1и завершает последовательность нажатием любого другого символа (включая символ новой строки):

$ ./bin2dec
1011010110
Digit #1 = 1
Digit #2 = 0
Digit #3 = 1
Digit #4 = 1
Digit #5 = 0
Digit #6 = 1
Digit #7 = 0
Digit #8 = 1
Digit #9 = 1
Digit #10 = 0

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

#!/bin/bash

arr=()
while : ; do
  read -n1
  case $REPLY in
    [01]) arr+=("$REPLY")
    ;;
    *) break
    ;;
  esac
done

for ((i=0; i<${#arr[@]}; ++i)); do
  printf 'Digit #%d = %d\n' "$i"  "${arr[i]}"
done

Обратите внимание на различную индексацию: хотя оба массива начинаются с нуля, нулевой элемент $@зарезервирован для имени файла скрипта.

Связанный контент