16

I have a file with jsonlines and would like to find empty values.

{"name": "Color TV", "price": "1200", "available": ""}
{"name": "DVD player", "price": "200", "color": null}

And would like to output empty and/or null values and their keys:

available: ""
color: null

I think it should be something like cat myexample | jq '. | select(. == "")', but is not working.

peak
  • 105,803
  • 17
  • 152
  • 177
Fernando César
  • 681
  • 1
  • 8
  • 16

4 Answers4

15

The tricky part here is emitting the keys without quotation marks in a way that the empty string is shown with quotation marks. Here is one solution that works with jq's -r command-line option:

to_entries[]
| select(.value | . == null or . == "")
| if .value == "" then .value |= "\"\(.)\"" else . end
| "\(.key): \(.value)"

Once the given input has been modified in the obvious way to make it valid JSON, the output is exactly as specified.

peak
  • 105,803
  • 17
  • 152
  • 177
  • Thanks! Corrected the input. I don't really understand the logic here. Can't we just filter keys with empty value? Why convert to_entries and then select entries and then... don't really know what happens there! – Fernando César Jun 20 '19 at 22:50
  • You might like to read the jq tutorial and the relevant sections of the jq manual -- see [tag:jq] – peak Jun 20 '19 at 23:01
  • What these to_entries[] mean and how do you use this with jq ? – VM47 May 03 '21 at 08:44
  • 1
    @VM47 - Please see the jq manual https://stedolan.github.io/jq/manual/ – peak May 03 '21 at 08:46
13

Some people may find the following jq program more useful for identifying keys with null or empty string values:

with_entries(select(.value |.==null or . == ""))

With the sample input, this program would produce:

{"available":""}
{"color":null}

Adding further information, such as the input line or object number, would also make sense, e.g. perhaps:

with_entries(select(.value |.==null or . == ""))
| select(length>0)
| {n: input_line_number} + .
peak
  • 105,803
  • 17
  • 152
  • 177
5

Take a look at this snippet https://blog.nem.ec/code-snippets/jq-ignore-nulls/

jq -r '.firstName | select( . != null )' file.json
Martín Coll
  • 3,368
  • 3
  • 37
  • 52
2

With a single with_entries(if .value == null or .value == "" then empty else . end) filter expression it's possible to filter out null and empty ("") values.

Without filtering:

echo '{"foo": null, "bar": ""}' | jq '.'
{
  "foo": null,
  "bar": ""
}

With filtering:

echo '{"foo": null, "bar": ""}' |  jq 'with_entries(if .value == null or .value == "" then empty else . end)'
{}
Miguel Ferreira
  • 1,282
  • 11
  • 27