Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

writing a bash array (of strings and special chars) to a file

Tags:

arrays

bash

I have a bash array OUTARRAY that I fill will values from processing an INARRAY. I frequently append to OUTARRAY special chars, namely \t and \n so it may look like:

OUTARRAY[j]="\n"

or

OUTARRAY[j]="${INARRAY[i]}\t"

in the end I dump the OUTARRAY in a file using

printf "%s" "${OUTARRAY[@]}" > ${OUTFILE}

the result I get however is, a single line file with all the special chars printed within:

\n2771\t2899\t7624\t2911\t\n2772\t2904\t7706\t2911\t\n2771\t2909

Instead, I want columned output. Something like

2771    2899    7624    2911
2772    2904    7706    2911

and so on. what do I do wrong? thank you

like image 879
nass Avatar asked May 30 '14 15:05

nass


People also ask

What does [- Z $1 mean in Bash?

$1 means an input argument and -z means non-defined or empty. You're testing whether an input argument to the script was defined when running the script.

How do I add elements to an array in Bash?

To append element(s) to an array in Bash, use += operator.

What does %% mean in Bash?

So as far as I can tell, %% doesn't have any special meaning in a bash function name. It would be just like using XX instead. This is despite the definition of a name in the manpage: name A word consisting only of alphanumeric characters and under- scores, and beginning with an alphabetic character or an under- score.


3 Answers

bash does not interpret C-style backslash escapes (\n) in quoted strings.

Instead, use the bash syntax $'\n':

OUTARRAY[j]=$'\n'
OUTARRAY[j]="${INARRAY[i]}"$'\t'

You might find it more readable if you start by defining:

NL=$'\n'
TAB=$'\t'

and then you can insert ${NL} and ${TAB} freely inside your double-quoted strings.


Alternatively, you can use a bash extension:

printf normally expands C-style backslash escapes in formats, but not in arguments. However, if you are using bash, then you can use the bash-specific %b printf format which expands backslash escapes in the corresponding argument. I don't really endorse this solution, but it should work without other modifications:

printf "%b" "${OUTARRAY[@]}" > ${OUTFILE}

By the way, it is not really good style to use ALL CAPS for bash variable names, because it increases the probability that they will clash with bash/system-specific environment variables.

like image 98
rici Avatar answered Oct 13 '22 05:10

rici


Instead of inserting the string \t or \n, insert actual tabs and newlines:

outarray[j]=$'\n'
outarray[j]=${inarray[i]}$'\t'

Now this is not really a good strategy. Instead, do not put your formatting in the array, but use printf to format how you want your array to be displayed: if you want 4 fields per line, separated by tabs:

printf '%s\t%s\t%s\t%s\n' "${outarray[@]}"

(btw, I lowercased your variable names, it's much better).

like image 5
gniourf_gniourf Avatar answered Oct 13 '22 05:10

gniourf_gniourf


The other answers are the right way to do it but it is possible to print your data as it is. You can use echo -ne and a loop to print your values:

$ arr=( "a\t" "b\n" "c\t" "d\n" )
$ for i in "${arr[@]}"; do echo -ne $i; done
a       b
c       d

The -n switch to echo removes the trailing newline and the -e means that backslash escape characters will be interpreted.

like image 1
Tom Fenech Avatar answered Oct 13 '22 07:10

Tom Fenech