shell脚本:将for循环的全部内容写入文件,而不仅仅是最后一行

时间:2017-06-22 16:59:27

标签: bash shell

我在带有索引和值的shell脚本中有一个数组。我能够打印这个数组。如何将整个数组写入文本文件?

我目前正在做的是:

for i in "${!array[@]}"; do
    printf "%s\t%s\n" "$i" "${array[$i]}" >outfile
done

但是,outfile中只有数组的最后一个元素。我该如何解决这个问题?

2 个答案:

答案 0 :(得分:4)

简单的答案是将重定向放在done之后,而不是放在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

请注意这些检查 - 我不会在此代码中再次执行这些检查,但是他们必须允许您的格式中的值注入其他键/值对,或允许&#34 ;值"实际指定其他键。

也就是说,要立即替换整个文件 ,应该使用写入和重命名模式来确保原子性。一般模式是:

tempfile=$(mktemp outfile.XXXXXX)
write_your_data >"$tempfile"
mv -- "$tempfile" outfile

write_your_data不一定是占位符 - 它也可以是一个封装循环本身的函数:

write_your_data() {
  local i
  for i in "${!array[@]}"; do
    printf "%s\t%s\n" "$i" "${array[$i]}"
  done
}

答案 1 :(得分:2)

为了清楚起见,您只看到最后一行的原因是因为您使用的是>而不是>>

>将输出重定向到文件,创建文件或覆盖已存在的文件。

>>也会重定向输出,但会附加到文件中......将其添加到文件末尾。

每当你的for循环迭代时,你就会重新创建"文件。

for i in "${!array[@]}"; do
    printf "%s\t%s\n" "$i" "${array[$i]}" >> outfile
done