2

If we have a hello.json

$ echo '{"hello": "world"}' > hello.json
$ cat hello.json
{"hello": "world"}

and try to add "foo": "bar" to it using jq, the file hello.json becomes an empty file.

$ cat hello.json | jq --arg bar bar '. + {foo: $bar}'  > hello.json
$ cat hello.json 

On the other hand, if we had instead written the new JSON payload to world.json, we get the expected contents in world.json.

$ echo '{"hello": "world"}' > hello.json
$ cat hello.json
{"hello": "world"}
$ cat hello.json | jq --arg bar bar '. + {foo: $bar}'  > world.json
$ cat world.json 
{
  "hello": "world",
  "foo": "bar"
}

Is there a way to do this without installing new utilities like sponge?

gameveloster
  • 901
  • 1
  • 6
  • 18
  • 3
    You can write to a temporary file and `mv` the temporary file to the original file. – erip May 29 '22 at 14:19

1 Answers1

1

This is not a jq problem, but how output redirection works in shells. When you redirect to a file with >, the file is truncated before the command is executed.

You have to write to a different file and then copy it over your old file. (Or use sponge).

As (generalized) code:

$ cmd < file > file.tmp
$ mv file.tmp file

or

$ cmd file > file.tmp
$ mv file.tmp file
knittl
  • 246,190
  • 53
  • 318
  • 364