使用bash编写文件的最有效方法是什么?

THI*_*ELP 4 bash file-io json echo

所以我必须用bash脚本编写一个JSON文件,我知道我可以做一些类似于echo 'something' >> $file慢慢构建文件的东西,但是echo重定向而不是真正的文件输出似乎有些"hacky".如果这是最好的方式,而不是一种hacky方式,我很乐意使用,echo,但我只是想知道是否有更好的方法从bash脚本输出文件.

Cha*_*ffy 12

有效地产生输出

echo是内置命令,而不是外部命令,所以它并不像你想象的那么低效.什么低效的是把>> filename每个月底echo.

这是不好的:

# EVIL!
echo "something" >file
echo "first line" >>file
echo "second line" >>file
Run Code Online (Sandbox Code Playgroud)

这很好:

# NOT EVIL!
{
  echo "something" >&3
  printf '%s\n' "first line" "$second line" >&3
  # ... etc ...
} 3>file
Run Code Online (Sandbox Code Playgroud)

...只打开一次输出文件,消除了主要的低效率.

要清楚:调用echo20次比调用cat一次效率要高得多,因为它cat是一个外部进程,而不是shell的一部分.运行echo "foo" >>file20次非常低效的是打开和关闭输出文件20次; 它echo本身不是.


正确生成JSON

不要使用cat,echo,printf,或其他任何东西的那种.相反,使用了解JSON的工具 - 任何其他方法都会导致潜在的错误(甚至可能是可利用的注入攻击)结果.

例如:

jq \
  --arg something "$some_value_here" \
  --arg another "$another_value" \
  '.["something"]=$something | .["another_value"]=$another' \
  <template.json >output.json
Run Code Online (Sandbox Code Playgroud)

...将生成一个JSON文件,基于template.json,something设置为shell变量中的值,"$some_value_here"another_value设置为第二个值.与朴素方法不同,这将正确处理包含文字引号或其他需要转义以正确表示的字符的变量值.


一个回声

所有上述内容都echo应该避免使用printf(使用适当的静态格式字符串).根据POSIX sh标准:

申请使用

除非-n(作为第一个参数)和转义序列都被省略,否则不可能在所有POSIX系统上都可以使用echo.

printf实用程序可以移植来模拟echo实用程序的任何传统行为,如下所示(假设IFS具有其标准值或未设置):

[...]

鼓励新应用程序使用printf而不是echo.

基本原理

由于回声效用在历史应用中的广泛使用,因此尚未过时.符合希望在没有s的情况下进行提示或者可能期望回显-n的应用程序应该使用从第九版系统派生的printf实用程序.

如上所述,echo以最简单的方式编写其参数.回声的两种不同历史版本以致命的不兼容方式变化.

BSD echo检查字符串-n的第一个参数,这会导致它抑制输出中的最后一个参数.

System V echo不支持任何选项,但允许其操作数内的转义序列,如OPERANDS部分中的XSI实现所述.

echo实用程序不支持实用程序语法指南10,因为历史应用程序依赖于echo来回显其所有参数,但BSD版本中的-n选项除外.


Mr.*_*ama 6

您可以使用cathere-文档格式:

cat <<'EOF' > output.json
{
    "key": "value",
    "num": 5,
    "tags": ["good", "bad"],
    "money": "$0"
}
EOF
Run Code Online (Sandbox Code Playgroud)

请注意here-document锚点周围的单个刻度.这可以防止插入文档的内容.没有它,$0可以替代.

如果将效率定义为原始速度而不是可读性,则应考虑使用Charles Duffy的答案,因为对于少量行(echo0.01s vs cat0.1s),它几乎快一个数量级.
如果需要创建大于几百行的文件,则应考虑除cat/ 之外的方法echo.