1 |
#!/usr/bin/env bash |
2 |
|
3 |
# NOTE: |
4 |
# -declare -A is required. |
5 |
# |
6 |
# Simply doing: |
7 |
# a=([aa]=b [foo]=bar ['a+1']=c) |
8 |
# gets utterly bizarre behavior. |
9 |
# |
10 |
# Associtative Arrays are COMPLETELY bash-specific. mksh doesn't even come |
11 |
# close. So I will probably not implement them, or implement something |
12 |
# slightly different, because the semantics are just wierd. |
13 |
|
14 |
# http://www.gnu.org/software/bash/manual/html_node/Arrays.html |
15 |
# TODO: Need a SETUP section. |
16 |
|
17 |
#### Literal syntax ([x]=y) |
18 |
declare -A a |
19 |
a=([aa]=b [foo]=bar ['a+1']=c) |
20 |
echo ${a["aa"]} |
21 |
echo ${a["foo"]} |
22 |
echo ${a["a+1"]} |
23 |
## STDOUT: |
24 |
b |
25 |
bar |
26 |
c |
27 |
## END |
28 |
|
29 |
#### set associative array to indexed array literal (bash anomaly) |
30 |
declare -A assoc=([k1]=foo [k2]='spam eggs') |
31 |
argv.py "${assoc[@]}" |
32 |
argv.py "${!assoc[@]}" |
33 |
|
34 |
# shouldn't this be disallowed? You're losing information. |
35 |
|
36 |
assoc=(foo 'spam eggs') |
37 |
argv.py "${assoc[@]}" |
38 |
argv.py "${!assoc[@]}" |
39 |
|
40 |
## STDOUT: |
41 |
['foo', 'spam eggs'] |
42 |
['k1', 'k2'] |
43 |
[] |
44 |
[] |
45 |
## END |
46 |
|
47 |
#### Can't initialize assoc array with indexed array |
48 |
declare -A A=(1 2 3) |
49 |
## status: 1 |
50 |
## BUG bash status: 0 |
51 |
|
52 |
#### Initializing indexed array with assoc array |
53 |
declare -a a=([xx]=1 [yy]=2 [zz]=3) |
54 |
#declare -a a=(1 2 3) |
55 |
argv.py "${a[@]}" |
56 |
## status: 1 |
57 |
## stdout-json: "" |
58 |
## BUG bash status: 0 |
59 |
## BUG bash STDOUT: |
60 |
['3'] |
61 |
## END |
62 |
|
63 |
#### create empty assoc array, put, then get |
64 |
declare -A A # still undefined |
65 |
argv.py "${A[@]}" |
66 |
argv.py "${!A[@]}" |
67 |
A['foo']=bar |
68 |
echo ${A['foo']} |
69 |
## STDOUT: |
70 |
[] |
71 |
[] |
72 |
bar |
73 |
## END |
74 |
|
75 |
#### retrieve keys with ! |
76 |
declare -A a |
77 |
var='x' |
78 |
a["$var"]=b |
79 |
a['foo']=bar |
80 |
a['a+1']=c |
81 |
for key in "${!a[@]}"; do |
82 |
echo $key |
83 |
done | sort |
84 |
## STDOUT: |
85 |
a+1 |
86 |
foo |
87 |
x |
88 |
## END |
89 |
|
90 |
#### retrieve values with ${A[@]} |
91 |
declare -A A |
92 |
var='x' |
93 |
A["$var"]=b |
94 |
A['foo']=bar |
95 |
A['a+1']=c |
96 |
for val in "${A[@]}"; do |
97 |
echo $val |
98 |
done | sort |
99 |
## STDOUT: |
100 |
b |
101 |
bar |
102 |
c |
103 |
## END |
104 |
|
105 |
#### coerce to string with ${A[*]}, etc. |
106 |
declare -A A |
107 |
A['X X']=xx |
108 |
A['Y Y']=yy |
109 |
argv.py "${A[*]}" |
110 |
argv.py "${!A[*]}" |
111 |
|
112 |
argv.py ${A[@]} |
113 |
argv.py ${!A[@]} |
114 |
## STDOUT: |
115 |
['xx yy'] |
116 |
['X X Y Y'] |
117 |
['xx', 'yy'] |
118 |
['X', 'X', 'Y', 'Y'] |
119 |
## END |
120 |
|
121 |
#### ${A[@]/b/B} |
122 |
# but ${!A[@]/b/B} doesn't work |
123 |
declare -A A |
124 |
A['aa']=bbb |
125 |
A['bb']=ccc |
126 |
A['cc']=ddd |
127 |
for val in "${A[@]//b/B}"; do |
128 |
echo $val |
129 |
done | sort |
130 |
## STDOUT: |
131 |
BBB |
132 |
ccc |
133 |
ddd |
134 |
## END |
135 |
|
136 |
#### ${A[@]#prefix} |
137 |
declare -A A |
138 |
A['aa']=one |
139 |
A['bb']=two |
140 |
A['cc']=three |
141 |
for val in "${A[@]#t}"; do |
142 |
echo $val |
143 |
done | sort |
144 |
## STDOUT: |
145 |
hree |
146 |
one |
147 |
wo |
148 |
## END |
149 |
|
150 |
#### ${assoc} disallowed in OSH, like ${assoc[0]} in bash |
151 |
declare -A a |
152 |
a=([aa]=b [foo]=bar ['a+1']=c) |
153 |
echo "${a}" |
154 |
## stdout-json: "\n" |
155 |
## OK osh stdout-json: "" |
156 |
## OK osh status: 1 |
157 |
|
158 |
#### length ${#a[@]} |
159 |
declare -A a |
160 |
a["x"]=1 |
161 |
a["y"]=2 |
162 |
a["z"]=3 |
163 |
echo "${#a[@]}" |
164 |
## stdout: 3 |
165 |
|
166 |
#### lookup with ${a[0]} -- "0" is a string |
167 |
declare -A a |
168 |
a["0"]=a |
169 |
a["1"]=b |
170 |
a["2"]=c |
171 |
echo 0 "${a[0]}" 1 "${a[1]}" 2 "${a[2]}" |
172 |
## STDOUT: |
173 |
0 a 1 b 2 c |
174 |
## END |
175 |
|
176 |
#### lookup with double quoted strings "mykey" |
177 |
declare -A a |
178 |
a["aa"]=b |
179 |
a["foo"]=bar |
180 |
a['a+1']=c |
181 |
echo "${a["aa"]}" "${a["foo"]}" "${a["a+1"]}" |
182 |
## STDOUT: |
183 |
b bar c |
184 |
## END |
185 |
|
186 |
#### lookup with single quoted string |
187 |
declare -A a |
188 |
a["aa"]=b |
189 |
a["foo"]=bar |
190 |
a['a+1']=c |
191 |
echo "${a['a+1']}" |
192 |
## stdout: c |
193 |
|
194 |
#### lookup with unquoted $key and quoted "$i$i" |
195 |
declare -A A |
196 |
A["aa"]=b |
197 |
A["foo"]=bar |
198 |
|
199 |
key=foo |
200 |
echo ${A[$key]} |
201 |
i=a |
202 |
echo ${A["$i$i"]} # note: ${A[$i$i]} doesn't work in OSH |
203 |
## STDOUT: |
204 |
bar |
205 |
b |
206 |
## END |
207 |
|
208 |
#### lookup by unquoted string doesn't work in OSH because it's a variable |
209 |
declare -A a |
210 |
a["aa"]=b |
211 |
a["foo"]=bar |
212 |
a['a+1']=c |
213 |
echo "${a[a+1]}" |
214 |
## stdout-json: "" |
215 |
## status: 1 |
216 |
## BUG bash stdout: c |
217 |
## BUG bash status: 0 |
218 |
|
219 |
#### bash bug: "i+1" and i+1 are the same key |
220 |
|
221 |
i=1 |
222 |
array=(5 6 7) |
223 |
echo array[i]="${array[i]}" |
224 |
echo array[i+1]="${array[i+1]}" |
225 |
|
226 |
# arithmetic does NOT work here in bash. These are unquoted strings! |
227 |
declare -A assoc |
228 |
assoc[i]=$i |
229 |
assoc[i+1]=$i+1 |
230 |
|
231 |
assoc["i"]=string |
232 |
assoc["i+1"]=string+1 |
233 |
|
234 |
echo assoc[i]="${assoc[i]}" |
235 |
echo assoc[i+1]="${assoc[i+1]}" |
236 |
|
237 |
echo assoc[i]="${assoc["i"]}" |
238 |
echo assoc[i+1]="${assoc["i+1"]}" |
239 |
|
240 |
## status: 1 |
241 |
## STDOUT: |
242 |
array[i]=6 |
243 |
array[i+1]=7 |
244 |
## END |
245 |
## BUG bash status: 0 |
246 |
## BUG bash STDOUT: |
247 |
array[i]=6 |
248 |
array[i+1]=7 |
249 |
assoc[i]=string |
250 |
assoc[i+1]=string+1 |
251 |
assoc[i]=string |
252 |
assoc[i+1]=string+1 |
253 |
## END |
254 |
|
255 |
#### Array stored in associative array gets converted to string (without strict-array) |
256 |
|
257 |
array=('1 2' 3) |
258 |
declare -A d |
259 |
d['key']="${array[@]}" |
260 |
argv.py "${d['key']}" |
261 |
## stdout: ['1 2 3'] |
262 |
|
263 |
#### Indexed array as key of associative array coerces to string (without shopt -s strict-array) |
264 |
|
265 |
declare -a array=(1 2 3) |
266 |
declare -A assoc |
267 |
assoc[42]=43 |
268 |
assoc["${array[@]}"]=foo |
269 |
|
270 |
echo "${assoc["${array[@]}"]}" |
271 |
for entry in "${!assoc[@]}"; do |
272 |
echo $entry |
273 |
done | sort |
274 |
|
275 |
## STDOUT: |
276 |
foo |
277 |
1 2 3 |
278 |
42 |
279 |
## |
280 |
|
281 |
#### Append to associative array value A['x']+='suffix' |
282 |
declare -A A |
283 |
A['x']='foo' |
284 |
A['x']+='bar' |
285 |
A['x']+='bar' |
286 |
argv.py "${A["x"]}" |
287 |
## STDOUT: |
288 |
['foobarbar'] |
289 |
## END |
290 |
|
291 |
#### Slice of associative array doesn't make sense in bash |
292 |
declare -A a |
293 |
a[xx]=1 |
294 |
a[yy]=2 |
295 |
a[zz]=3 |
296 |
a[aa]=4 |
297 |
a[bb]=5 |
298 |
#argv.py ${a["xx"]} |
299 |
argv.py ${a[@]: 0: 3} |
300 |
argv.py ${a[@]: 1: 3} |
301 |
argv.py ${a[@]: 2: 3} |
302 |
argv.py ${a[@]: 3: 3} |
303 |
argv.py ${a[@]: 4: 3} |
304 |
argv.py ${a[@]: 5: 3} |
305 |
## stdout-json: "" |
306 |
## status: 1 |
307 |
## BUG bash STDOUT: |
308 |
['2', '1', '5'] |
309 |
['2', '1', '5'] |
310 |
['1', '5', '4'] |
311 |
['5', '4', '3'] |
312 |
['4', '3'] |
313 |
['3'] |
314 |
## END |
315 |
## BUG bash status: 0 |
316 |
|
317 |
#### bash variable can have an associative array part and a string part |
318 |
|
319 |
# and $assoc is equivalent to ${assoc[0]}, just like regular arrays |
320 |
declare -A assoc |
321 |
assoc[1]=1 |
322 |
assoc[2]=2 |
323 |
echo ${assoc[1]} ${assoc[2]} ${assoc} |
324 |
assoc[0]=zero |
325 |
echo ${assoc[1]} ${assoc[2]} ${assoc} |
326 |
assoc=string |
327 |
echo ${assoc[1]} ${assoc[2]} ${assoc} |
328 |
## STDOUT: |
329 |
1 2 |
330 |
1 2 zero |
331 |
1 2 string |
332 |
## END |
333 |
## N-I osh stdout-json: "" |
334 |
## N-I osh status: 1 |
335 |
|
336 |
#### Associative array expressions inside (( )) with keys that look like numbers |
337 |
declare -A assoc |
338 |
assoc[0]=42 |
339 |
(( var = ${assoc[0]} )) |
340 |
echo $var |
341 |
(( var = assoc[0] )) |
342 |
echo $var |
343 |
## STDOUT: |
344 |
42 |
345 |
42 |
346 |
## END |
347 |
## N-I osh status: 1 |
348 |
## N-I osh STDOUT: |
349 |
42 |
350 |
## END |
351 |
|
352 |
#### (( A[5] += 42 )) |
353 |
declare -A A |
354 |
(( A[5] = 10 )) |
355 |
(( A[5] += 6 )) |
356 |
echo ${A[5]} |
357 |
## STDOUT: |
358 |
16 |
359 |
## END |
360 |
|
361 |
#### (( A[5] += 42 )) with empty cell |
362 |
shopt -u strict-arith # default zero cell |
363 |
declare -A A |
364 |
(( A[5] += 6 )) |
365 |
echo ${A[5]} |
366 |
## STDOUT: |
367 |
6 |
368 |
## END |