Arrays in unix shell?

271,187

Solution 1

The following code creates and prints an array of strings in shell:

#!/bin/bash
array=("A" "B" "ElementC" "ElementE")
for element in "${array[@]}"
do
    echo "$element"
done

echo
echo "Number of elements: ${#array[@]}"
echo
echo "${array[@]}"

Result:

A
B
ElementC
ElementE

Number of elements: 4

A B ElementC ElementE

Solution 2

in bash, you create array like this

arr=(one two three)

to call the elements

$ echo "${arr[0]}"
one
$ echo "${arr[2]}"
three

to ask for user input, you can use read

read -p "Enter your choice: " choice

Solution 3

Bourne shell doesn't support arrays. However, there are two ways to handle the issue.

Use positional shell parameters $1, $2, etc.:

$ set one two three
$ echo $*
one two three
$ echo $#
3
$ echo $2
two

Use variable evaluations:

$ n=1 ; eval a$n="one" 
$ n=2 ; eval a$n="two" 
$ n=3 ; eval a$n="three"
$ n=2
$ eval echo \$a$n
two

Solution 4

#!/bin/bash

# define a array, space to separate every item
foo=(foo1 foo2)

# access
echo "${foo[1]}"

# add or changes
foo[0]=bar
foo[2]=cat
foo[1000]=also_OK

You can read the ABS "Advanced Bash-Scripting Guide"

Solution 5

Your question asks about "unix shell scripting", but is tagged bash. Those are two different answers.

The POSIX specification for shells does not have anything to say about arrays, as the original Bourne shell did not support them. Even today, on FreeBSD, Ubuntu Linux, and many other systems, /bin/sh does not have array support. So if you want your script to work in different Bourne-compatible shells, you shouldn't use them. Alternatively, if you are assuming a specific shell, then be sure to put its full name in the shebang line, e.g. #!/usr/bin/env bash.

If you are using bash or zsh, or a modern version of ksh, you can create an array like this:

myArray=(first "second element" 3rd)

and access elements like this

$ echo "${myArray[1]}" # for bash/ksh; for zsh, echo $myArray[2]
second element

You can get all the elements via "${myArray[@]}". You can use the slice notation ${array[@]:start:length} to restrict the portion of the array referenced, e.g. "${myArray[@]:1}" to leave off the first element.

The length of the array is ${#myArray[@]}. You can get a new array containing all the indexes from an existing array with "${!myArray[@]}".

Older versions of ksh before ksh93 also had arrays, but not the parenthesis-based notation, nor did they support slicing. You could create an array like this, though:

set -A myArray -- first "second element" 3rd 
Share:
271,187
Arunachalam
Author by

Arunachalam

fun

Updated on July 22, 2022

Comments

  • Arunachalam
    Arunachalam almost 2 years

    How do I create an array in unix shell scripting?

  • ghostdog74
    ghostdog74 over 14 years
    breaks on directory names with spaces. use a while read loop of change IFS to take care of that.
  • plesiv
    plesiv almost 11 years
    Bash supports arrays. Not sure about original Bourne shell, but bash is more prevalent these days...
  • Keith Thompson
    Keith Thompson almost 11 years
    csh does have arrays.
  • SourceSeeker
    SourceSeeker almost 11 years
    @KeithThompson: It's not documented in the man page but the functionality does appear to be present in at least some versions.
  • Keith Thompson
    Keith Thompson over 10 years
    The man page doesn't mention "arrays" by that name, but see the documentation of the set command (set name=(wordlist)) and the "Variable substituion" section ($name[selector] and ${name[selector]}). As far as I know, csh has always supported arrays. See, for example, the $path array variable, which mirrors the $PATH environment variable.
  • beatgammit
    beatgammit over 10 years
    @zplesivcak - ... on GNU/Linux, since it's a GNU thing. For example, FreeBSD doesn't ship with bash (it's installable from ports though). Scripts written assuming bash features aren't portable, and they're noticably slower slower than most Bourne shell implementations (like dash, which is common on GNU/Linux distributions). bash is a nice interactive shell, but it's slow for scripting.
  • zserge
    zserge over 10 years
    $* is considered harmful. Normally, $@ is preferred since it does the same, but keeps spaces. $@ is expanded as "$1" "$2" "$3" ... "$n", while $* is expanded as "$1x$2x$3x...$n", where x is $IFS separator (most likely, space).
  • Alex Dupuy
    Alex Dupuy about 10 years
    A more concise way to show the last element is echo "${array[@]:(-1)}". This eliminates the need to write the array variable name twice.
  • Mark Reed
    Mark Reed over 8 years
    Unquoted, $@ is the same as $*; the difference only shows up when quoted: "$*" is one word, while "$@" preserves the original word breaks.
  • Mark Reed
    Mark Reed over 8 years
    The question is tagged bash, so bash-specific responses are appropriate, but it's certainly true that one shouldn't assume that /bin/sh is bash.
  • Charles Duffy
    Charles Duffy almost 6 years
    Please reconsider suggesting the ABS as a learning resource -- it's in many ways to bash what W3Schools is to HTML and Javascript, having lots of Google juice but showcasing bad practices in many of its examples, and rarely and inadequately updated. The bash-hackers' wiki is a much better resource; so is the BashGuide.
  • GhostCat
    GhostCat over 5 years
    Nice answer, Great start for a newbie. And welcome to upvote levels ;-)
  • mhyousefi
    mhyousefi over 4 years
    The space-separated declaration does NOT work with /bin/sh throwing an error line 1: syntax error: unexpected "(". Do you know of an alternative?
  • mhyousefi
    mhyousefi over 4 years
    The space-separated declaration does NOT work with /bin/sh throwing an error line 1: syntax error: unexpected "(". Do you know of an alternative?