Code for Concinnity

beautiful and elegant solutions


Iterating Bash arrays with spaces

The problem

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
#!/bin/sh

$ a=(hello world foo bar)
$ for i in #{a[*]}; do echo $i; done

# Expected output:
#   hello
#   world
#   foo
#   bar

# so far so good:
#   hello
#   world
#   foo
#   bar

$ a=("hello world" "foo bar")
$ for i in #{a[*]}; do echo $i; done

# Expected output:
#   hello world
#   foo bar

# omg:
#   hello
#   world
#   foo
#   bar

The problem is caused by the affect that Bash uses space as array element separator internally.

Failed attempt

1
2
3
4
5
6
7
8
9
10
11
#!/bin/sh

$ a=("hello world" "foo bar")
$ for i in "#{a[*]}"; do echo $i; done

# Expected output:
#   hello world
#   foo bar

# zomg!
#   hello world foo bar

The solution

The solution lies in the magical $@ expansion. When the $@ expansion is put in a quote, the shell automatically expands each element properly quoted:

1
2
3
4
5
6
7
8
9
10
11
12
#!/bin/sh

a=("hello world" "foo bar")
for i in "#{a[@]}"; do echo $i; done

# Expected output:
#   hello world
#   foo bar

# yay!
#   hello world
#   foo bar
Published by kizzx2, on April 10th, 2010 at 1:27 am. Filled under: Useful tips Tags: , , , No Comments