CARVIEW |
Bash Arrays
If you're used to a "standard" *NIX shell you may not be familiar with bash's array feature. Although not as powerful as similar constructs in the P languages (Perl, Python, and PHP) and others, they are often quite useful.
Bash arrays have numbered indexes only, but they are sparse, ie you don't have to define all the indexes. An entire array can be assigned by enclosing the array items in parenthesis:
arr=(Hello World)Individual items can be assigned with the familiar array syntax (unless you're used to Basic or Fortran):
arr[0]=Hello arr[1]=WorldBut it gets a bit ugly when you want to refer to an array item:
echo ${arr[0]} ${arr[1]}To quote from the man page:
The braces are required to avoid conflicts with pathname expansion.
In addition the following funky constructs are available:
${arr[*]} # All of the items in the array ${!arr[*]} # All of the indexes in the array ${#arr[*]} # Number of items in the array ${#arr[0]} # Length of item zeroThe ${!arr[*]} is a relatively new addition to bash, it was not part of the original array implementation.
The following example shows some simple array usage (note the "[index]=value" assignment to assign a specific index):
#!/bin/bash
array=(one two three four [5]=five)
echo "Array size: ${#array[*]}"
echo "Array items:"
for item in ${array[*]}
do
printf " %s\n" $item
done
echo "Array indexes:"
for index in ${!array[*]}
do
printf " %d\n" $index
done
echo "Array items and indexes:"
for index in ${!array[*]}
do
printf "%4d: %s\n" $index ${array[$index]}
done
Array size: 5 Array items: one two three four five Array indexes: 0 1 2 3 5 Array items and indexes: 0: one 1: two 2: three 3: four 5: five
Note that the "@" sign can be used instead of the "*" in constructs such as ${arr[*]}, the result is the same except when expanding to the items of the array within a quoted string. In this case the behavior is the same as when expanding "$*" and "$@" within quoted strings: "${arr[*]}" returns all the items as a single word, whereas "${arr[@]}" returns each item as a separate word.
The following example shows how unquoted, quoted "*", and quoted "@" affect the expansion (particularly important when the array items themselves contain spaces):
#!/bin/bash
array=("first item" "second item" "third" "item")
echo "Number of items in original array: ${#array[*]}"
for ix in ${!array[*]}
do
printf " %s\n" "${array[$ix]}"
done
echo
arr=(${array[*]})
echo "After unquoted expansion: ${#arr[*]}"
for ix in ${!arr[*]}
do
printf " %s\n" "${arr[$ix]}"
done
echo
arr=("${array[*]}")
echo "After * quoted expansion: ${#arr[*]}"
for ix in ${!arr[*]}
do
printf " %s\n" "${arr[$ix]}"
done
echo
arr=("${array[@]}")
echo "After @ quoted expansion: ${#arr[*]}"
for ix in ${!arr[*]}
do
printf " %s\n" "${arr[$ix]}"
done
Number of items in original array: 4 first item second item third item After unquoted expansion: 6 first item second item third item After * quoted expansion: 1 first item second item third item After @ quoted expansion: 4 first item second item third item
Mitch Frazier is an Associate Editor for Linux Journal.
Special Reports: DevOps
Have projects in development that need help? Have a great development operation in place that can ALWAYS be better? Regardless of where you are in your DevOps process, Linux Journal can help!
With deep focus on Collaborative Development, Continuous Testing and Release & Deployment, we offer here the DEFINITIVE DevOps for Dummies, a mobile Application Development Primer, advice & help from the experts, plus a host of other books, videos, podcasts and more. All free with a quick, one-time registration. Start browsing now...
Geek Guides
Practical (and free!) books for the most technical people on the planet. Newly available books include:
Plus many more.
Trending Topics
October 2015 Issue of Linux Journal: Raspberry Pi | Oct 01, 2015 |
October 2015 Video Preview | Oct 01, 2015 |
System Status as SMS Text Messages | Sep 29, 2015 |
Libreboot on an X60, Part I: the Setup | Sep 28, 2015 |
New Products | Sep 25, 2015 |
Vagrant Simplified | Sep 25, 2015 |
- October 2015 Issue of Linux Journal: Raspberry Pi
- SUSE – “Will not diverge from its Open Source roots!”
- Vagrant Simplified
- System Status as SMS Text Messages
- October 2015 Video Preview
- New Products
- Libreboot on an X60, Part I: the Setup
- Disney's Linux Light Bulbs (Not a "Luxo Jr." Reboot)
- Bluetooth Hacks
- Linux and the Internet of Things
Comments
Script fails?
The example script fails on my Solaris 9 server using GNU Bash-2.05. Of course you do mention that the ${!array[*]} is fairly new so it appears not to be in my version of bash. Posting what version you are using would be helpful.
Here's the output I got.
#
Array size: 5
Array items:
one
two
three
four
five
Array indexes:
Array items and indexes:
Thanks!
SQLITE
Hello,
Thanks for this article, Using bash arrays is MUST to avoid using tmp files and unnessary loops in some cases ...
But for large amount of data, I'd highly recommend using sqlite databases which is much faster and allows better functions ...
Think big
When I have a lot of data to store I use a Sun Fire X4500 server with 48 Terabytes of attached storage. What I like most about this is that it's a one to one swap for using bash.
Geez...
Mitch Frazier is an Associate Editor for Linux Journal.
Array in bash is really
Array in bash is really helpful. Here is how we can join two arrays in bash
https://unstableme.blogspot.com/2008/12/join-two-arrays-in-bash-script.html
what about speed
hmm, I've tried once to use bash arrays in a simple script, which looked for specified strings in all cvs revisions of a file. But it seemed to work rather slowly.
Trolls
So he tried it "ONCE" and decided it was slow? Hmmmm...
Pretty weak
Since you don't really give us any details to support your assertion: no source for your script and no details of other bash based implementations that proved faster, I have to assume that the slowness was related to CVS, or to searching, or possibly to bash in general, but I doubt it had anything do with bash arrays.
Mitch Frazier is an Associate Editor for Linux Journal.
speed
That's clearly just a troll. Bash is useful and the author doesn't need to justify its relevance. :D