Write output to a file after piped to jq

ShellIo Redirection

Shell Problem Overview


How can I write a piped output that went through jq to a file in shell

Example:

curl api.example.com | jq > call.txt

won't work. Neither does

(curl api.example.com | jq) > call.txt

Help!

Edit: So doing curl api.example.com > call.txt works just fine. So it has to do with piping it to jq

Shell Solutions


Solution 1 - Shell

Just calling jq without a filter will throw errors if stdout isn't a terminal

$ curl https://jsonplaceholder.typicode.com/posts/1 | jq > test.txt
jq - commandline JSON processor [version 1.5-1-a5b5cbe]
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
[...]

Try jq '.' (i.e: pretty-print the input JSON):

$ curl https://jsonplaceholder.typicode.com/posts/1 | jq '.' > test.txt
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100   292  100   292    0     0   1698      0 --:--:-- --:--:-- --:--:--  1707

Note that the filter is not really optional:

From man jq:

JQ(1)                                                                                JQ(1)

NAME
       jq - Command-line JSON processor

SYNOPSIS
       jq [options...] filter [files...]

According to the tip of the master branch... your described (and my observed) behaviour is not expected...

Older versions of jq have the following: (here)

if (!program && isatty(STDOUT_FILENO) && !isatty(STDIN_FILENO))
  program = ".";

i.e: use a default filter if stdout is a TTY, and stdin is not a TTY.

This behaviour appears to be corrected in commit 5fe05367, with the following snippet of code:

if (!program && (!isatty(STDOUT_FILENO) || !isatty(STDIN_FILENO)))
  program = ".";

Solution 2 - Shell

My incantation:

$ cat config.json

{
    "ProgramSettings":
    {
        "version": "1.0"
    },
    "ProgramSecrets":
    {
    	"AWS_ACCESS_KEY_ID": "",
    	"AWS_SECRET_ACCESS_KEY": ""
    }
}

assume you want remove object 'ProgramSecrets' from JSON file:

$ echo $(cat config.json | jq 'del(.ProgramSecrets)') > config.json
$ cat config.json
{ "ProgramSettings": { "version": "1.0" } }

Solution 3 - Shell

Just try:

curl api.example.com | jq '.' > call.txt

It works fine for me.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionsupersizeView Question on Stackoverflow
Solution 1 - ShellAttieView Answer on Stackoverflow
Solution 2 - ShellJarikusView Answer on Stackoverflow
Solution 3 - ShellJoy Jedidja NdjamaView Answer on Stackoverflow