Bash: Append to array using while-loop
From FVue
Contents
Problem
How can I append values to an array from within a while-loop? Of course, the values may contain special characters.
Solution
Change IFS (Field Seperator) to a newline.
foo() { local IFS=$'\t\n' # Set IFS to Tab & Newline (no space) a=( "b c" ) # Array to append to, containing one element "b c" # Three values to append, separated by newline append="d e f\"g \$PWD" # NOTE: The dash (-) prevents error "unbound variable" when `-u' or # `-o nounset' is set and `a' is empty array. a=( ${a[@]-} $( echo "$append" | { while read i; do echo $i done } )) } # foo()
Running the code above, shows array `a' contains four elements:
$ foo $ declare -p a declare -a a='([0]="b c" [1]="d e" [2]="f\"g" [3]="\$PWD")'
Caveat: commented quote in subshell causes error up to and including bash-3.1
Do not use quotes (single or double) within comments within a subshell, because there's a bug in bash (<= 3.1):
$ echo $(#' > ) bash: bad substitution: no closing `)' in $(#' ) $
This bug has been fixed in bash-3.2.
See also: Commented quotes in subshells cause syntax errors - Bug-bash mailing list
See also
- Bash Reference Manual - Arrays
- The Array reference. Did you know you can separate array items using
IFS='x'; echo "${array[*]}";
- Assorted tips
- Example for passing and returning arrays to a function
<amazon asin="0596526784" height="240" name="product" width="120"/>
Journal
20071217
Trying `eval':
foo() { a=( "b b" "c c" ) append="d e f\"g \$PWD" eval a=( "${a[@]}" $(echo "$append" | { while read i; do echo "$i" | sed -e "s/\"/\\\\\\\\\\\\&/g" \ -e "s/.*/\"&\"/" #| \ sed -e "s/[][(){}<>\",:;^&!$&=?\`|\\ ']/\\\\\\\\\\\\&/g" done })) for i in "${a[@]}"; do echo i: $i; done } foo
Advertisement