Printing an array to a file with each element of the array in a new line in bash

I am trying the contents of an array into a file with each element of the array in a new line in the file.

IFS=$'n'   
echo "${mtches[@]}" > sample1.txt

The content of mtches is “qwe” and ” asd”. But the sample1.txt file contains qwe asd in a single line. Why is it not taking IFS value into the picture?

Answers:

Thank you for visiting the Q&A section on Magenaut. Please note that all the answers may not help you solve the issue immediately. So please treat them as advisements. If you found the post helpful (or not), leave a comment & I’ll get back to you as soon as possible.

Method 1

You should use printf instead of echo:

printf "%sn" "${mtches[@]}"

If mtches is empty that would still output one empty line. To account for that:

{ [ "${#mtches[@]}" -eq 0 ] || printf '%sn' "${mtches[@]}"; } > file

In bash (and also POSIX shells), you often use Positional Parameters array as"[email protected]" instead of "$*", unless you have a special reason. That’s also true in shells that support regular arrays, from man bash – section Arrays:

Any element of an array may be referenced using ${name[subscript]}.
The braces are required to avoid conflicts with the shell’s filename
expansion operators. If the subscript is ‘@’ or ‘*’, the word expands
to all members of the array name. These subscripts differ only when
the word appears within double quotes. If the word is double-quoted,
${name[*]} expands to a single word with the value of each array
member separated by the first character of the IFS variable, and
${name[@]} expands each element of name to a separate word. When there
are no array members, ${name[@]} expands to nothing. If the
double-quoted expansion occurs within a word, the expansion of the
first parameter is joined with the beginning part of the original
word, and the expansion of the last parameter is joined with the last
part of the original word. This is analogous to the expansion of the
special parameters ‘@’ and ‘*’

Only use "${array[*]}" when you want join all array elements to a string.

Method 2

You want to use ${mtches[*]} instead.

When you use "${mtches[@]}", it doesn’t matter what the value of $IFS is, bash will split the array into multiple arguments. What you want is a single argument with each array element joined by n. ${mtches[*]} accomplishes this.

Also as a temporary way of setting $IFS, you can do:

( IFS=$'n'; echo "${mtches[*]}" > sample1.txt )

Then you don’t have to bother with setting it back.

Method 3

Using for:

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

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[@]}"

Method 4

for ENTRY in ${ARRAY[@]}; do
    echo $ENTRY
done > outfile

Nice and readable and doesn’t mean messing with IFS. It also means you can customise the handling of each line.


All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0

0 0 votes
Article Rating
Subscribe
Notify of
guest

0 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
0
Would love your thoughts, please comment.x
()
x