web-dev-qa-db-ja.com

bashで配列値をシフトする方法

例として6つのマウントポイントフォルダーを構築する

/data/sdb
/data/sdc
/data/sdd
/data/sde
/data/sdf
/data/sdg

だから私たちは配列を使ってこの簡単なbashスクリプトを書きました

folder_mount_point_list="sdb sdc sdd sde sdf sdg"

folderArray=( $folder_mount_point_list )

counter=0
for i in disk1 disk2 disk3 disk4 disk4 disk5 disk6
do
folder_name=${folderArray[counter]}
mkdir /data/$folder_name
let counter=$counter+1
done

counterlet = $ counter = counter + 1なしでコードを変更したい

次の配列値を取得するために、各ループを配列にシフトすることは可能ですか?

のようなものとして

${folderArray[++]}
8
yael

総論。次のように配列を定義しても意味がありません。

folder_mount_point_list="sdb sdc sdd sde sdf sdg"
folderArray=( $folder_mount_point_list )

代わりにこれを行います:

folderArray=(sdb sdc sdd sde sdf sdg)

今あなたの質問に:

set -- sdb sdc sdd sde sdf sdg
for folder_name; do
    mkdir "/data/$folder_name"
done

または

set -- sdb sdc sdd sde sdf sdg
while [ $# -gt 0 ]; do
    mkdir "/data/$1"
    shift
done
10
Hauke Laging

タイトルの質問に答えるために、部分文字列/部分配列表記で配列を「シフト」できます。 (shift自体は定位置パラメーターのみで機能します。)

_$ a=(a b c d e)
$ a=("${a[@]:1}")
$ echo "${a[@]}"
b c d e
_

同様に、配列から最後の項目を「ポップ」するには:a=("${a[@]:0:${#a[@]} - 1}" )または_unset "a[${#a[@]}-1]"_

したがって、必要に応じて、これを行うことができます。

_a=(foo bar doo)
b=(123 456 789)
while [ "${#a[@]}" -gt 0 ] ; do
    echo "$a $b"
    a=("${a[@]:1}")
    b=("${b[@]:1}")
done
_

しかし、それは配列を破壊するので、いつものようにインデックスを付けるだけの方が良いかもしれません。または、代わりに連想配列を使用することもできます。

_declare -A arr=([foo]=123 [bar]=456 [doo]=789)
_
13
ilkkachu

すべての値をループするだけで、シフトは必要ありません。

folderArray=(sdb sdc sdd sde sdf sdg)

for folder in "${folderArray[@]}"; do
    mkdir "/data/$folder"
done
4
PesaThe

そのためのループは必要ありません。

folderArray=(sdb sdc sdd sde sdf sdg)
IFS=,
eval mkdir /data/{"${folderArray[*]}"}

トリックは、添え字*"${array[*]}")で配列が二重引用符で囲まれている場合、各配列要素の値がIFS変数の最初の文字で区切られた単一のWordに展開されることです。その後、ブレース展開メカニズムを使用して、/data/を各配列メンバーにアタッチし、全体をevaluateします。

3
jimmij