Super User is a question and answer site for computer enthusiasts and power users. It's 100% free, no registration required.

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

I want to write out a bash array variable to a file, with each element on a new line. I could do this with a for loop, but is there another (cleaner) way to join the elements with \n?

share|improve this question
up vote 21 down vote accepted

Here's a way that utilizes bash parameter expansion and its IFS special variable.

$ System=('s1' 's2' 's3' 's4 4 4')
$ ( IFS=$'\n'; echo "${System[*]}" )

We use a subshell to avoid overwriting the value of IFS in the current environment. In that subshell, we then modify the value of IFS so that the first character is a newline (using $'...' quoting). Finally, we use parameter expansion to print the contents of the array as a single word; each element is separated by the first charater of IFS.

To capture to a variable:

$ var=$( IFS=$'\n'; echo "${System[*]}" )

If your bash is new enough (4.2 or later), you can (and should) still use printf with the -v option:

$ printf -v var "%s\n" "${System[@]}"

In either case, you may not want the final newline in var. To remove it:

$ var=${var%?}    # Remove the final character of var
share|improve this answer
Thanks, is there a way to output this to a variable? – ACyclic Aug 16 '12 at 16:26
Updated to show how to capture to a variable. – chepner Aug 16 '12 at 16:34
Shouldn't the last example be var=${var%?} instead? This is not a regular expression, so . will match only a period character. – musiphil Sep 13 '13 at 17:49

You can use printf to print each array item on its own line:

 $ System=('s1' 's2' 's3' 's4 4 4')
 $ printf "%s\n"  "${System[@]}"
s4 4 4
share|improve this answer
awk -v sep='\n' 'BEGIN{ORS=OFS="";for(i=1;i<ARGC;i++){print ARGV[i],ARGC-i-1?sep:""}}' "${arr[@]}"


perl -le 'print join "\n",@ARGV' "${arr[@]}"


python -c 'import sys;print "\n".join(sys.argv[1:])' "${arr[@]}"


sh -c 'IFS=$'\''\n'\'';echo "$*"' '' "${arr[@]}"


lua <(echo 'print(table.concat(arg,"\n"))') "${arr[@]}"


tclsh <(echo 'puts [join $argv "\n"]') "${arr[@]}"


php -r 'echo implode("\n",array_slice($argv,1));' -- "${arr[@]}"


ruby -e 'puts ARGV.join("\n")' "${arr[@]}"

that's all I can remind so far.

share|improve this answer

Above solutions are pretty much it, but the original question asks for output to file:

$ a=(a b c d e)
$ ( IFS=$'\n'; echo "${a[*]}" ) > /tmp/file
$ cat /tmp/file

Notes: 1) 'echo' provides the final newline 2) If this file will just be read in by bash again, then declare -p may be the serialization wanted.

share|improve this answer

Using for:

for each in "${alpha[@]}"
  echo "$each"

Using history; note this will fail if your values contain !:

history -p "${alpha[@]}"

Using basename; note this will fail if your values contain /:

basename -a "${alpha[@]}"

Using shuf; note that results might not come out in order:

shuf -e "${alpha[@]}"
share|improve this answer

Your Answer


By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.