Contents missing using jq to update a JSON file

Viewed 58

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?

1 Answers

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
Related