简体   繁体   中英

Using bash and jq and reading in a json file with \n in the contents

Need some help with jq and reading in a json file that must have \n values because I need to import it into something else later. How can I have jq interpret it as a literal \n instead of the line breaks below....? Notice my json has a \n and I want it like that. I don't want it to treat it as a carriage return like it's doing in the output

file.json (note the \n in the description)

{
"person": [
    {
        "name": "Alex",
        "age": "10",
        "description": "A really\nnice kid"
    },
    {
        "name": "James",
        "age": "17",
        "description": "One mature\nBoy who\ndoes his homework"
    }
]

}

Script:

jq -r -M '.person[] | .name + " " + .description' file.json  \
| while IFS=$' ' read -r  nameX  descriptionX; do
echo "${nameX} ${descriptionX}"
echo "----------------------------------------done---------------------"
done

Wrong Output right now it's doing this:

Alex A really
----------------------------------------done---------------------
nice kid
----------------------------------------done---------------------
James One mature
----------------------------------------done---------------------
Boy who
----------------------------------------done---------------------
does his homework
----------------------------------------done---------------------

It should look like this, but it looks like the one above. How can I make it look like this.

Alex A really\nnice kid
----------------------------------------done---------------------
James One mature\nBoy who\ndoes his homework
----------------------------------------done---------------------

You can actually do this directly in jq , by replacing actual newlines (which are represented by \n in JSON strings) with literal \ and n characters:

$ jq -r -M '.person[] | .name + " " + (.description | gsub("\n"; "\\n"))' file.json
Alex A really\nnice kid
James One mature\nBoy who\ndoes his homework

And feeding it into your while read loop:

$ jq -r -M '.person[] | .name + " " + (.description | gsub("\n"; "\\n"))' file.json |
> while IFS=$' ' read -r  nameX  descriptionX; do
> echo "${nameX} ${descriptionX}"
> echo "----------------------------------------done---------------------"
> done
Alex A really\nnice kid
----------------------------------------done---------------------
James One mature\nBoy who\ndoes his homework
----------------------------------------done---------------------

The requirements are unclear, so here are three approaches that might be (or might be the basis for) solutions:

1. jq+sed

jq  -M '.person[] | .name + " " + .description' | sed -e 's/^"//' -e 's/"$//'

2. jq+read+sed

jq  -M '.person[] | .name + " " + .description'  |
  while IFS=$' ' read -r line ; do
    printf "%s\n" "$line" | sed -e 's/^"//' -e 's/"$//'
    echo "----------------------------------------done---------------------"
  done

3. jq + (read+sed)^2

jq -M '.person[] | .name, .description'  |
  threewhile IFS=$' ' read -r name ; do
    name=$(sed -e 's/^"//' -e 's/"$//' <<< $name)
    read -r description
    description=$(sed -e 's/^"//' -e 's/"$//' <<< $description)
    echo "$name $description" 
    echo "----------------------------------------done---------------------"
  done

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM