bash函数输入$ 1只处理字符串&的第一个字。格式化问题

时间:2016-08-06 16:55:37

标签: json bash function echo quoting

我的BASH功能:

json_format () {
        echo '{
                "question": "';echo "$1";echo '",' 
}

有:

json_format ${questions[$Q_counter]}

回归:

{
                "question": "
VM
",

而不是预期的json格式和字符串:

{
    "question": "VM CPU is at 100% and you'r jumpbox creds be broken! What do you do?",

字符串似乎在第一个单词" VM"之后的空格处被切断,并且这些echo命令的格式稍微偏离。我怎样才能纠正我的功能?谢谢!

1 个答案:

答案 0 :(得分:1)

从shell生成JSON的理想方法是使用实​​际了解格式的jq等工具:

json_format() {
  jq -n --arg q "$1" '{"question": $q}'
}

...或者,如果您有Python解释器,也可以使用built-in json module

json_format() {
  python -c 'import sys, json; print json.dumps({"question": sys.argv[1]})' "$1"
}

但是,如果您没有这些工具,至少会尽最大努力逃避:

json_format() {
  local s=$1
  s=${s//'\'/'\\'}   # replace \ with \\
  s=${s//'"'/'\"'}   # replace " with \"
  s=${s//$'\n'/'\n'} # replace newline literals with \n
  printf '{\n\t"question": "%s"\n}\n' "$s"
}

...或者,一次处理一个值:

json_format() {
  local s=$1
  s=${s//'\'/'\\'}   # replace \ with \\
  s=${s//'"'/'\"'}   # replace " with \"
  s=${s//$'\n'/'\n'} # replace newline literals with \n
  printf '%s\n' "$s"
}

...为每个要格式化的字符串单独调用,如:

cat <<EOF
{
  "question": "$(json_format "$question")",
  "image": "$(json_format "$image_url")",
  "choices": [ ],
  "correct": [ "$(json_format "$answer")" ],
  "explanation": "$(json_format "$explanation")"
}
EOF

这将适用于天真方法将产生有效但实际上不是有效JSON的情况。例如,考虑一下:

# naive string substitution will fail here because it won't escape double quotes
json_format 'How do you spell "hello" in Spanish?'

# naive string substitution will fail here because it won't escape the newline
json_format $'This question has\ntwo lines'

# naive string substitution will fail here because it won't escape the backslash
json_format 'This question ends in a backslash: \'

注意,在上述所有内容中,引用 - 确保字符串作为单个参数传递。