我在带有索引和值的shell脚本中有一个数组。我能够打印这个数组。如何将整个数组写入文本文件?
我目前正在做的是:
for i in "${!array[@]}"; do
printf "%s\t%s\n" "$i" "${array[$i]}" >outfile
done
但是,outfile
中只有数组的最后一个元素。我该如何解决这个问题?
答案 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