3

Background

I want to be able to pass a json file to WP CLI, to iteratively create posts.

So I thought I could create a JSON file:

[
    {
        "post_type": "post",
        "post_title": "Test",
        "post_content": "[leaflet-map][leaflet-marker]",
        "post_status": "publish"
    },
    {
        "post_type": "post",
        "post_title": "Number 2",
        "post_content": "[leaflet-map fitbounds][leaflet-circle]",
        "post_status": "publish"
    }
]

and iterate the array with jq:

cat posts.json | jq --raw-output .[]

I want to be able to iterate these to execute a similar function:

wp post create \
  --post_type=post \
  --post_title='Test Map' \
  --post_content='[leaflet-map] [leaflet-marker]' \
  --post_status='publish'

Is there a way I can do this with jq, or similar?

The closest I've gotten so far is this:

> for i in $(cat posts.json | jq -c .[]); do echo $i; done

But this seems to take issue with the (valid) spaces in the strings. Output:

{"post_type":"post","post_title":"Test","post_content":"[leaflet-map][leaflet-marker]","post_status":"publish"}
{"post_type":"post","post_title":"Number
2","post_content":"[leaflet-map
fitbounds][leaflet-circle]","post_status":"publish"}

Am I way off with this approach, or can it be done?

bozdoz
  • 12,550
  • 7
  • 67
  • 96
  • c.f. https://stedolan.github.io/jq/manual/ - `-c` explicitly says to squeeze out whitespace such as newline characters. Try `--indent n` inside the loop, but `-c` to generate your data. Loop with `while read -r i;do echo "$i"|jq --indent 2 '.'; echo "==="; done < <( jq -c '.[]' posts.json ) ` – Paul Hodges Mar 01 '19 at 22:12

3 Answers3

7

Use a while to read entire lines, rather than iterating over the words resulting from the command substitution.

while IFS= read -r obj; do
    ...
done < <(jq -c '.[]' posts.json)
chepner
  • 497,756
  • 71
  • 530
  • 681
  • great idea. couldn't for the life of me get this working until stumbling upon your solution – Nik Oct 24 '20 at 19:34
1

Maybe this would work for you:

Make a bash executable, maybe call it wpfunction.sh

#!/bin/bash

wp post create \
  --post_type="$1"\
  --post_title="$2" \
  --post_content="$3" \
  --post_status="$4"

Then run jq on your posts.json and pipe it into xargs

jq -M -c '.[] | [.post_type, .post_title, .post_content, .post_status][]' \
posts.json | xargs -n4 ./wpfunction`

I am experimenting to see how this would handle post_content that contained quotes...

1

First generate an array of the arguments you wish to pass then convert to a shell compatible form using @sh. Then you could pass to xargs to invoke the command.

$ jq -r '.[] | ["post", "create", (to_entries[] | "--\(.key)=\(.value|tojson)")] | @sh' input.json | xargs wp
Jeff Mercado
  • 129,526
  • 32
  • 251
  • 272