1

I want to send a big json with long string field by curl, how should I crop it to multiple lines? For example:

curl -X POST 'localhost:3000/upload' \
  -H 'Content-Type: application/json'
  -d "{
    \"markdown\": \"# $TITLE\\n\\nsome content with multiple lines....\\n\\nsome content with multiple lines....\\n\\nsome content with multiple lines....\\n\\nsome content with multiple lines....\\n\\n\"
  }"

3 Answers 3

2

Use a tool like jq to generate your JSON, rather than trying to manually construct it. Build the multiline string in the shell, and let jq encode it. Most importantly, this avoids any potential errors that could arise from TITLE containing characters that would need to be correctly escaped when forming your JSON value.

my_str="# $TITLE
some content with multiple lines...
some content with multiple lines...
some content with multiple lines..."

my_json=$(jq --argjson v "$my_str" '{markdown: $v}')

curl -X POST 'localhost:3000/upload' \
  -H 'Content-Type: application/json' \
  -d "$my_json"

curl has the ability to read the data for -d from standard input, which means you can pipe the output of jq directly to curl:

jq --argjson v "$my_str" '{markdown: $v}' | curl ... -d@-
2

You can split anything to multiple lines using the technique already in your post, by terminating lines with \. If you need to split in the middle of a quoted string, terminate the quote and start a new one. For example these are equivalent:

echo "foobar"
echo "foo""bar"
echo "foo"\
     "bar"

But for your specific example I recommend a much better way. Creating the JSON in a double-quoted string is highly error prone, because of having to escape all the internal double-quotes, which becomes hard to read and maintain as well. A better alternative is to use a here-document, pipe it to curl, and use -d@- to make it read the JSON from stdin. Like this:

formatJson() {
    cat << EOF
{
  "markdown": "some content with $variable in it"
}
EOF
}

formatJson | curl -X POST 'localhost:3000/upload' \
  -H 'Content-Type: application/json'
  -d@-
1

If I were you, I'd save the JSON to a file:

curl -X POST 'localhost:3000/upload' \
    -H 'Content-Type: application/json' \
    -d "$(cat my_json.json)"
4
  • The json data is generated by the shell script it self, rather than load from file.
    – acrazing
    Commented Dec 14, 2018 at 4:01
  • 2
    Curl can do -d @my_json.json for exactly this. Commented Dec 14, 2018 at 4:10
  • @kcats If the data is generated by another command, what do you need to split? Your question implies you have a large hard-coded literal.
    – chepner
    Commented Dec 14, 2018 at 4:11
  • @chepner the data's markdown field is generated by the variables, it contains some information generated by the script. In other words, I hope to generate a json with a big string field. I could not wrap the string because JSON does not support it.
    – acrazing
    Commented Dec 14, 2018 at 4:30

Not the answer you're looking for? Browse other questions tagged or ask your own question.