代码之家  ›  专栏  ›  技术社区  ›  Matt

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

  •  -3
  • Matt  · 技术社区  · 8 年前

    我的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 回复  |  直到 8 年前
        1
  •  1
  •   Charles Duffy    8 年前

    从shell生成JSON的理想方法是使用以下工具 jq 真正理解格式的:

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

    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: \'
    

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