venkatsai
venkatsai

Reputation: 113

shell script : write entire contents of for loop to file, not only last line

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

Answers (2)

MerrillFraz
MerrillFraz

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

Charles Duffy
Charles Duffy

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

Related Questions