bash - 原因のように開始点を設定して配列を並べ替えます。

bash - 原因のように開始点を設定して配列を並べ替えます。

私のスクリプトは次の設定を使用します。

#!/bin/bash

array=(C G D A E B)

if [[ "$1" = "--setstart" ]] || [[ "$1" = "-s" ]]; then
    if [ -n "$2" ]; then

        array=($(sed "s/.*$2 /$2 /" <<< "${array[@]}"))

    else
        printf "\nno argument...!\n"
    fi
fi

for a in "${array[@]}"; do
    printf "%s " "$a"
done    
echo

この--setstartオプションを使用すると、配列の読み取りを開始する場所を選択できます(このsedコマンドは、現在この問題を解決するために私が考えることができる唯一の方法です)。

スクリプト自体はprints:オプションなしで実行され、C G D A E B 値を設定すると--setstartその時点で配列を印刷するため、--setstart Dprint:doesですD A E B

array最初に切り取った部分が最後まで入るように、これをループに印刷するオプションをどのように導入しますか?設定がD印刷されたと仮定すると:D A E B C G

答え1

Bashサブストリング(サブ配列)拡張を使用する(例:${parameter:offset:length})...

array=(A B C D E F)

start=$1
# handle negative offsets
[[ $start -lt 0 ]] && start=$((${#array[@]} + start))

# the star of the show, create array2 from two sub-arrays of array
array2=("${array[@]:$start}" "${array[@]:0:$start}")

echo "${array2[@]}" 

ここでは、説明のために元の配列を新しく配置された配列に配置します。 (いくつかの明らかな境界検査などを省略しました。)

$ ./rotate.sh 3
D E F A B C

修正する:負のオフセットを処理するために上記のスクリプトを修正しました。イカチュウの答え)...

$ ./rotate.sh -2
E F A B C D

アップデート2:「A」から「F」までの文字の1つ(質問の例とより密接に一致する)を許可するスクリプトの場合は、次のようstart=$1に置き換えます。

# Convert [A-F] to ASCII code then normalize to [0-5]
LC_CTYPE=C start=$(( $(printf %d "'$1") - 65 ))

もちろん、ソートされた文字配列がない場合は、任意の配列要素を処理するために次のようなものが必要です。

idx=0
for elem in "${array[@]}"; do
    [[ $elem = $1 ]] && break
    ((idx++))
done
start=$idx

答え2

モジュラスを使用します。クン/クッシュ:

$ cat rotate.sh
#!/bin/bash
array=(A B C D E F)
n=${#array[@]}
start=${1-0}
i=0;
while (( i < n )) ; do
    printf "%s " "${array[(start + i) % n]}"
    (( i++ ))
done
echo

Zsh は 1 で配列インデックスを開始するので、少し調整が必要です。最初のコマンドラインパラメータは開始位置を設定し、負の数にすることがstartできます。

$ ./rotate.sh 2
C D E F A B 

値で始点を見つけるには、修正が簡単でなければなりません。

関連情報