Reputation: 113
I have an array in a shell script with index and value . I am able to print this array. How do i write the entire array into a text file?
What I'm currently doing is this:
for i in "${!array[@]}"; do
printf "%s\t%s\n" "$i" "${array[$i]}" >outfile
done
However, only the last element of the array is present in outfile
. How can I fix this?
Upvotes: 0
Views: 188
Reputation: 79
Just to be clear, the reason you are only seeing the last line is because you are using >
instead of >>
.
>
redirects the output to a file, either creating it or overwriting what was already there.
>>
also redirects the output, but appends to a file...adding it to the end of it.
Every time your for
loop iterated, you were "recreating" the file.
for i in "${!array[@]}"; do
printf "%s\t%s\n" "$i" "${array[$i]}" >> outfile
done
Upvotes: 2
Reputation: 295353
The easy answer is to put the redirection after the done
, not on the printf
:
for key in "${!array[@]}"; do
value=${array[$key]}
[[ $key = *[$'\t\n']* ]] && continue # security: disallow keys with tabs or newlines
[[ $value = *[$'\n']* ]] && continue # security: disallow values with newlines
printf "%s\t%s\n" "$i" "${array[$i]}"
done >outfile
Note those checks -- I'm not doing them again later in this code, but they're necessary to allow a value in your format to inject other key/value pairs, or to allow "values" to actually specify other keys.
That said, to replace an entire file at once, one should use a write-and-rename pattern to ensure atomicity. The general pattern is:
tempfile=$(mktemp outfile.XXXXXX)
write_your_data >"$tempfile"
mv -- "$tempfile" outfile
write_your_data
need not be a placeholder -- it could also be a function encapsulating the loop itself:
write_your_data() {
local i
for i in "${!array[@]}"; do
printf "%s\t%s\n" "$i" "${array[$i]}"
done
}
Upvotes: 4