Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

JQ giving usage error only if stdout is redirected

Tags:

bash

curl

jq

I have a curl command

 curl -H "Accept: application/json" https://icanhazdadjoke.com/

Which returns the JSON (note: I chose this api because it has no auth so everyone can help test, it returns a formatted json but most API's return a flat json with no formatting... One line)

 {
  "id": "5wAIRfaaUvc", 
  "joke": "What do you do when a blonde throws a grenade at you? Pull the pin and throw it back.", 
  "status": 200
}

When I pipe to JQ, jq responds as expected. I pipe to jq to ensure I have a formatted readable json

curl -H "Accept: application/json" https://icanhazdadjoke.com/ | jq

Returns

  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100   110  100   110    0     0    320      0 --:--:-- --:--:-- --:--:--   321
{
  "id": "NCAIYLeNe",
  "joke": "I fear for the calendar, it’s days are numbered.",
  "status": 200
}

BUT when I pipe the output of JQ to a text file (I want a formatted version to be saved for readability, not the plain unformatted json)I get an error

curl -H "Accept: application/json" https://icanhazdadjoke.com/ | jq > file.txt

Returns

jq - commandline JSON processor [version 1.5]
Usage: jq [options] <jq filter> [file...]

    jq is a tool for processing JSON inputs, applying the
    given filter to its JSON text inputs and producing the
    filter's results as JSON on standard output.
    The simplest filter is ., which is the identity filter,
    copying jq's input to its output unmodified (except for
    formatting).
    For more advanced filters see the jq(1) manpage ("man jq")
    and/or https://stedolan.github.io/jq

    Some of the options include:
     -c     compact instead of pretty-printed output;
     -n     use `null` as the single input value;
     -e     set the exit status code based on the output;
     -s     read (slurp) all inputs into an array; apply filter to it;
     -r     output raw strings, not JSON texts;
     -R     read raw strings, not JSON texts;
     -C     colorize JSON;
     -M     monochrome (don't colorize JSON);
     -S     sort keys of objects on output;
     --tab  use tabs for indentation;
     --arg a v  set variable $a to value <v>;
     --argjson a v  set variable $a to JSON value <v>;
     --slurpfile a f    set variable $a to an array of JSON texts read from <f>;
    See the manpage for more options.
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100   141  100   141    0     0    317      0 --:--:-- --:--:-- --:--:--   316
(23) Failed writing body
like image 762
Goldfish Avatar asked Jan 29 '23 02:01

Goldfish


1 Answers

If you want jq to format the same JSON it got as input, pass . as the script for it to run:

curl -H "Accept: application/json" https://icanhazdadjoke.com/ | jq . > file.txt

From the manual:

Identity: .

The absolute simplest filter is . . This is a filter that takes its input and produces it unchanged as output. That is, this is the identity operator.

Since jq by default pretty-prints all output, this trivial program can be a useful way of formatting JSON output from, say, curl.

like image 161
Charles Duffy Avatar answered Jan 31 '23 15:01

Charles Duffy