2

Haven't used jq before but I'm wanting to build a shell script that will get a JSON response and extract just the values. To learn I thought I would try on my blog's WP API but for some reason I'm getting an error of:

jq: error (at :322): Cannot index array with string "slug"

When researching for and testing previous questions:

The above reading I've tried to code:

URL="http://foobar.com"
RESPONSE=$(curl -so /dev/null -w "%{http_code}" $URL)
WPAPI="/wp-json/wp/v2"
IDENTIFIER="categories"

if (("$RESPONSE" == 200)); then
    curl -s {$URL$WPAPI"/"$IDENTIFIER"/"} | jq '.' >> $IDENTIFIER.json
    result=$(jq .slug $IDENTIFIER.json)
    echo $result
else
    echo "Not returned status 200";
fi

An additional attempt changing the jq after the curl:

curl -s {$URL$WPAPI"/"$IDENTIFIER"/"} | jq '.' | $IDENTIFIER.json
result=(jq -r '.slug' $IDENTIFIER.json)
echo $result

I can modify the uncompress with the python JSON tool:

result=(curl -s {$URL$WPAPI"/"$IDENTIFIER"/"} | python -m json.tool > $IDENTIFIER.json)

I can save the JSON to a file but when I use jq I cannot get just the slug and here are my other trys:

catCalled=$(curl -s {$URL$WPAPI"/"$IDENTIFIER"/"} | python -m json.tool | ./jq -r '.slug')
echo $catCalled

My end goal is to try to use jq in a shell script and build a slug array with jq. What am I doing wrong in my jq and can I use jq on a string without creating a file?


Return from curl after uncompress per comment request:

[
  {
    "id": 4,
    "count": 18,
    "description": "",
    "link": "http://foobar.com/category/foo/",
    "name": "Foo",
    "slug": "foo",
    "taxonomy": "category",
  },
  {
    "id": 8,
    "count": 9,
    "description": "",
    "link": "http://foobar.com/category/bar/",
    "name": "Bar",
    "slug": "bar",
    "taxonomy": "category",
  },
  {
    "id": 5,
    "count": 1,
    "description": "",
    "link": "http://foobar.com/category/mon/",
    "name": "Mon",
    "slug": "mon",
    "taxonomy": "category",
  },
  {
    "id": 11,
    "count": 8,
    "description": "",
    "link": "http://foobar.com/category/fort/",
    "name": "Fort",
    "slug": "fort",
    "taxonomy": "category",
  }
]

eventually my goal is trying to get the name of the slug's into an array like:

catArray=('foo','bar','mon', 'fort')
DᴀʀᴛʜVᴀᴅᴇʀ
  • 7,681
  • 17
  • 73
  • 127

3 Answers3

2

There are 2 issues here:

  1. slug is not a root level element in your example json. The root level element is an array. If you want to access the slug property of each element of the array, you can do so like this:

    jq '.[].slug' $IDENTIFIER.json
    
  2. Your example json has trailing commas after the last property of each array element. Remove the commas after "taxonomy": "category".

If I take your sample json, remove the errant commas, save it to a plain text file called test.json and run the following command:

jq '.[].slug' test.json

I get the following output:

"foo"
"bar"
"mon"
"fort"
Asaph
  • 159,146
  • 25
  • 197
  • 199
0

Preprocessing

Unfortunately, the JSON-like data shown as having been produced by curl is not strictly JSON. jq does not have a "relaxed JSON" mode, so in order to use jq, you will have to preprocess the JSON-like data, e.g. using hjson (see http://hjson.org/):

$ hjson -j input.qjson > input.json

jq

With the JSON in input.json:

$ jq -c 'map(.slug)' input.json
["foo","bar","mon","fort"]
peak
  • 105,803
  • 17
  • 152
  • 177
0

your string is not json, notice how the last member of your objects ends with a comma,

{foo:"bar",baz:9,}

this is legal in javascript, but it's illegal in json. if you are supposed to be receiving json from that endpoint, then contact the people behind it and tell them to fix the bug (it's breaking the json specs by ending objects's last member with a comma, which is illegal in json.) - until it's fixed, i guess you can patch it with a little regex, but it's a dirty quickfix, and probably not very reliable, but running it through

perl -p -0777 -e 's/\"\,\s*}/\"}/g;' makes it legal json..

hanshenrik
  • 19,904
  • 4
  • 43
  • 89