数値に文字列を追加する方法

数値に文字列を追加する方法

最近、2 進数を 10 進数に変換できるスクリプトを作成しようとしています。これまでに作成したものは次のとおりです。

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

かなり長いスクリプトであることは承知しています。しかし、時間をかけてこのスクリプトを調べてみてください。

readif条件文内の行を見ると、readステートメントが数値を割り当てている変数自体が数値であることがわかります。Bash 構文では、これは機能しません。変数を n1、n2、n3、n4... のようにしたいのですが、ステートメント内を見るとelif [[ $digits > 3 ]]; then、無限の桁数をデコードできる for ループがあることがわかります。現在、変数のn数値に文字列を追加する方法がわかりません。しかし、変数に$digitno文字列を追加する方法を誰か知っている方がいるのではないかと考えていました。n$digitno

どのような助けでもいただければ幸いです。

答え1

単純な連結を使用して、数値に文字列を追加できます。

$ i=3
$ echo n$i
n3

しかし、それはあなたの本当の目的にはあまり役立ちません。不確定な数のユーザー入力をインデックス付き変数に割り当てる方法

すでにお分かりのとおり、コマンドでは 、 などの1名前2の変数は使用できません。bashの変数名は少なくとも3read始めるアルファベット文字またはアンダースコアで始まる場合、展開$1、、などはシェルの$2$3位置パラメータ

$1スクリプトで... を本当に使用したい場合は$n、シェル組み込み関数を使用して実際に実行できますset。POSIX では までのパラメータのサポートのみが必要ですが、bash では任意の数をサポートすることに注意してください(ただし、9 を超えるインデックスの場合は、たとえばを 10番目の位置パラメータとして、をリテラル と連結したものとして$9区別するために中括弧を使用する必要があります)。例:${10}$10$10

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

ユーザーは、文字のシーケンスを入力し01他の文字 (改行を含む) を入力してシーケンスを終了します。

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

インデックスが異なることに注意してください。両方の配列はゼロベースですが、 のゼロ番目の要素は$@スクリプト ファイルの名前用に予約されています。

関連情報