配列を分割すると、出力は変数に文字列としてキャプチャされます。
スライスを直接使用する場合は、別の項目になります。
文字列に変換せずに変数にスライス配列を格納する方法は?
この問題を解決する他の方法や方法はありますか?
例:
# setting IFS to this, no need to quote anything
IFS=$'\n'
mapfile -t arr < <(for i in {1..6}; do echo $i; done)
declare -p arr
declare -a arr=([0]="1" [1]="2" [2]="3" [3]="4" [4]="5" [5]="6")
# $() or `` give the same results
slc=`echo ${arr[@]:0:3}`
# proving that when the slice is saved as a var, it's a string
for i in $slc; do echo $i; done
1 2 3
# proving that when the slice is used directly the items are separate
for i in ${arr[@]:0:3}; do echo $i; done
1
2
3
IFS=$'\n'
引用符の有無にかかわらず、結果が同じ場合は、許可された回答と連携します。
IFS=$'\n'
slc=(${arr[@]:0:3})
for i in ${slc[@]}; do echo $i; done
1
2
3
答え1
存在する:
echo ${arr[@]:0:3}
まず、引用符を忘れました。これは、拡張が分割+glob(使用IFS=$'\n'
、改行でまだ分割、まだglobbingを実行)の影響を受け、任意のecho
データに使用できないものを使用することを意味します。
echo
複数の引数が渡され(スライスの要素はさらに分割+globの影響を受けます)、スペースで区切って印刷します。
そして:
var=`echo...`
(しかし、これは使用しなければならない廃止されたコマンドの代替形式ですvar=$(echo...)
。)
シェルはこの出力(末尾の改行を除く)を次に収集します。スカラーecho
これはスカラー変数の割り当て構文であるため、いずれにせよ、各要素が開始および終了する場所に関する情報は、すべてをストリームにまとめた後、長い間失われました。
スライスを変数に保存するには配列変数が必要で、配列割り当て構文を使用します。
$ arr=( '*' $'\n' '' 'element '{4..6} ) # ¹
$ slc=( "${arr[@]:0:3}" )
$ typeset -p arr slc
declare -a arr=([0]="*" [1]=$'\n' [2]="" [3]="element 4" [4]="element 5" [5]="element 6")
declare -a slc=([0]="*" [1]=$'\n' [2]="")
あなたも同じです:
@slc = @arr[0..2] # in perl
slc = $arr( `{seq 3} ) # in rc
set slc $arr[1..3] # in fish
slc=( "${arr[1,3]}" ) # in yash
slc=( "${(@)arr[1,3]}" ) # in zsh
そして要素を繰り返します。
for i in "${slc[@]}"; do
something with "$i"
done
または、エイリアスをreadarray -td '' arr < <(printf '%s\0' '*' $'\n' '' 'element '{4..6}
使用する必要readarray
がある場合、または名前を誤って指定する必要がある場合は、mapfile
bash変数または組み込みパラメータにNUL文字を含めることができないことを利用してください。