1 #!/bin/bash
2 # query2.sh
3
4 numbers=(53 8 12 9 784 69 8 7 1)
5 i=4
6
7 echo ${numbers[@]} # <--- this echoes "53 8 12 9 784 69 8 7 1" to stdout.
8 echo ${numbers[i]} # <--- this echoes "784" to stdout.
9
10 unset numbers[i]
11
12 echo ${numbers[@]} # <--- this echoes "53 8 12 9 69 8 7 1" to stdout.
13 echo ${numbers[i]} # <--- stdout is blank.
配列が12行のstdoutに基づいて更新されたように見えますが、13行のstdoutが空であるのはなぜですか?
では、予想される答え「69」を得るにはどうすればよいですか?
答え1
unset
要素を削除します。残りの要素の番号を再度付けません。
私たちはこれを使ってdeclare -p
何が起こっているのかを確認できますnumbers
。
$ unset "numbers[i]"
$ declare -p numbers
declare -a numbers=([0]="53" [1]="8" [2]="12" [3]="9" [5]="69" [6]="8" [7]="7" [8]="1")
観察にはnumbers
もう要素がありません4
。
他の例
観察する:
$ a=()
$ a[1]="element 1"
$ a[22]="element 22"
$ declare -p a
declare -a a=([1]="element 1" [22]="element 22")
配列にはa
2から21までの要素はありません。 Bashでは、配列インデックスが連続的である必要はありません。
インデックス番号の再割り当てに推奨される方法
numbers
欠けている要素を持つ配列から始めましょう4
。
$ declare -p numbers
declare -a numbers=([0]="53" [1]="8" [2]="12" [3]="9" [5]="69" [6]="8" [7]="7" [8]="1")
インデックスを変更するには:
$ numbers=("${numbers[@]}")
$ declare -p numbers
declare -a numbers=([0]="53" [1]="8" [2]="12" [3]="9" [4]="69" [5]="8" [6]="7" [7]="1")
これで要素番号があり、4
値があります69
。
1つのステップで要素を削除して配列番号を再割り当てする別の方法
再定義してみましょうnumbers
。
$ numbers=(53 8 12 9 784 69 8 7 1)
提案通りトビースペートコメントには、5番目の要素(インデックス4)を削除し、1つのステップで残りの要素の番号を再割り当てする方法があります。
$ numbers=("${numbers[@]:0:4}" "${numbers[@]:5}")
$ declare -p numbers
declare -a numbers=([0]="53" [1]="8" [2]="12" [3]="9" [4]="69" [5]="8" [6]="7" [7]="1")
ご覧のとおり、5番目の要素が削除され、残りのすべての要素の番号が再割り当てされます。
${numbers[@]:0:4}
Slices array numbers
:要素0から始めて、最初の4つの要素を取得します。
同様に${numbers[@]:5}
、配列を分割すると、numbers
要素5から配列の終わりまですべての要素が取得されます。
配列のインデックスを取得する
これ価値${a[@]}
見つけるために配列を取得するために使用できます。索引(または鍵)この値に対応するを使用してください${!a[@]}
。
たとえば、配列にnumbers
要素が欠落していると考えてみましょう4
。
$ declare -p numbers
declare -a numbers=([0]="53" [1]="8" [2]="12" [3]="9" [5]="69" [6]="8" [7]="7" [8]="1")
どのインデックスが割り当てられているかを確認するには、次の手順に従ってください。
$ echo "${!numbers[@]}"
0 1 2 3 5 6 7 8
今回も4
インデックスリストにその値がありません。
文書
からman bash
:
組み込み
unset
関数は配列を破壊するために使用されます。unset name[subscript]
indexから配列要素を削除しますsubscript
。インデックス配列の負の添え字は、上記のように説明されます。パス名拡張による不要な副作用を防ぐために注意を払う必要があります。unset name
、name
配列はどこにありますか、unset name[subscript]
どこにsubscript
ありますか?*
または@
、配列全体を削除します。
答え2
bash
inのような配列は、ksh
実際の配列ではなく、連想配列(またはいわゆる話す配列)に近いです。まれな配列)。実際の配列を持つシェルの場合rc
、、、、、などのes
シェルを見ることができます(たとえ/これらのシェルには多くの問題があるので避けるのが最善です)。fish
yash
zsh
csh
tcsh
存在するzsh
:
a=(1 2 3 4 5)
a[3]=() # remove the 3rd element
a[1,3]=() # remove the first 3 elements
a[-1]=() # remove the last element
(zshでは、unset 'a[3]'
との互換性を向上させるために実際に空の文字列に設定されていますksh
。)
存在するyash
:
a=(1 2 3 4 5)
array -d a 3 # remove the 3rd element
array -d a 1 2 3 # remove the first 3 elements
array -d a -1 # remove the last element
(fish
/とは異なり、Bourneのようなシェルではありません):bash
zsh
set a 1 2 3 4 5
set -e a[3] # remove the 3rd element
set -e a[1..3] # remove the first 3 elements
set -e a[-1] # remove the last element
in es
( rc
Bourne のようなものではない に基づいている)
a = 1 2 3 4 5
a = $a(... 2 4 ...) # remove the 3rd element
a = $a(4 ...) # remove the first 3 elements
a = $a(... `{expr $#a - 1}) # remove the last element
# or a convoluted way that avoids forking expr:
a = $a(... <={@{*=$*(2 ...); return $#*} $a})
ksh
一緒にするbash
これにより、その配列を通常の配列として使用できます。
a=("${a[@]}")
これにより、インデックスリストが連続していないか、各削除または挿入操作の後にゼロから始まらない可能性があります。また、ksh
/bash
配列は1ではなく0から始まることに注意してください($@
(ある意味では除く))。
これは実際に要素を照合し、順番にインデックス0、1、2...に移動します。
また、次の事項を引用する必要がありますnumber[i]
。
unset 'number[i]'
それ以外の場合は、unset numberi
呼び出されている現在のディレクトリにファイルがある場合は効果的に実行されます。numberi