Cómo agregar una cadena a un número

Cómo agregar una cadena a un número

Recientemente intenté crear un script que pueda convertir un número binario en decimal. Esto es lo que tengo hasta ahora:

#!/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

Es un guión bastante largo, lo sé. Pero intente tomarse el tiempo para examinar este script.

Si observa cualquiera de las readlíneas dentro del condicional if, verá que las variables a las que las readdeclaraciones asignan los números son en sí mismas números. Con la sintaxis Bash, eso no funcionará. Quiero que las variables sean como n1, n2, n3, n4... y así sucesivamente. Pero, si observa el interior de la elif [[ $digits > 3 ]]; thendeclaración, puede ver que hay un bucle for que permite decodificar un número infinito de dígitos. Ahora, no conozco ninguna forma de agregar la cadena nal número en la variable $digitno. Pero me preguntaba si alguno de ustedes podría descubrir cómo agregar la cadena na la $digitnovariable.

Cualquier ayuda será apreciada.

Respuesta1

Puedes agregar una cadena a un número usando una concatenación simple:

$ i=3
$ echo n$i
n3

sin embargo, eso no ayuda mucho con tu verdadero objetivo aquí, que parece sercómo asignar un número indeterminado de entradas del usuario a variables indexadas.

Como ya descubrió, no puede usar variables denominadas 1, 2, 3etc. en un readcomando. Aparte del hecho de que los nombres de las variables de bash deben al menoscomenzarcon un carácter alfabético o un guión bajo, las expansiones $1, $2, $3etc. están reservadas para el shellparámetros posicionales.

Si realmente desea utilizar $1... $nen su secuencia de comandos, puede hacerlo utilizando el setshell incorporado. Tenga en cuenta que, mientras que POSIX solo requiere soporte para parámetros hasta $9, bash admite un número arbitrario (aunque para índices superiores a 9 necesitará usar llaves para eliminar la ambigüedad entre, por ejemplo, ${10}como el décimo parámetro posicional y $10como la concatenación de $1con literal 0). . Por ejemplo:

#!/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

El usuario ingresa una secuencia de caracteres 0y 1, finalizando la secuencia presionando cualquier otro carácter (incluida la nueva línea):

$ ./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

Alternativamente, podrías hacer esencialmente lo mismo con una matriz definida por el usuario:

#!/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

Tenga en cuenta la indexación diferente; aunque ambas matrices tienen base cero, el elemento cero de $@está reservado para el nombre del archivo de secuencia de comandos.

información relacionada