How to pass individual elements in an array in JQ to xargs

Viewed 289

I have an array like such:

[
  {
    "customer": {
      "id": "61ae22891dbcb5200f4af298",
      "customerId": "C0001346",
      "companyName": "Real Constructions",
      "displayName": "Real Constructions",
      "fullName": "NiyatiU",
      "email": "niyati@curbwaste.com",
      "phone": "(987) 654-3209"
    },
    "address": {
      "streetName": "NY",
      "state": "NY",
      "city": "NY",
      "zipcode": "39092"
    }
  },
  {
    "customer": {
      "id": "61ae29f31dbcb5200f4af2b2",
      "customerId": "C0001347",
      "companyName": "UK Reality",
      "displayName": "UK Reality",
      "fullName": "VatsalShah",
      "email": "vatsal@curbwaste.com",
      "phone": "(766) 688-1348"
    },
    "address": {
      "streetName": "Queens",
      "state": "NY",
      "city": "Queens",
      "zipcode": "11354"
    }
  }
]

and I would like to pass each object as a seperate param to xargs and curl. Psuedo code like

jq '. | map(@json) | join("\\0")' http/customer/us/customers.json \
  | xargs -0 -n 1 -I % curl -X POST http://localhost:3000/customers -d '%'

But then I get:

xargs: insufficient space for argument

because the json element is too big, I'd assume. I'd prefer not write a bunch of files.

2 Answers
jq -j 'map(@json) | join("\u0000")' http/customer/us/customers.json |
   xargs -0 -I % curl -X POST http://localhost:3000/customers -d %

Since @json never produces any line feeds, the following would also work:

jq -r '.[] | @json' http/customer/us/customers.json |
   xargs -I % curl -X POST http://localhost:3000/customers -d %

Demo on jq play

  • --join-output/-j prints the string as-is rather that rather than printing a JSON string literal that produces the string. Doesn't add any line feeds, not even a trailing one.

  • --raw-output/-r prints the string as-is rather that rather than printing a JSON string literal that produces the string. Adds a line feed after each string.

  • "\\0" doesn't produce a NUL. You want "\u0000" for that.

  • . | is useless.

  • There's no difference between '%' and %. They both pass % to xargs.

  • -n 1 is useless. -I implies -L 1, which renders -n 1 redundant.

  • {} is more commonly used as the replacement expression than %. But % is also fine, so I didn't change this.

Use the --join-output (or -j) option to output raw text with no newlines, and use \u0000 to create the NUL character:

jq -j 'map(@json) | join("\u0000")' http/customer/us/customers.json \
  | xargs -0 -n 1 -I % curl -X POST http://localhost:3000/customers -d '%'
Related