Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How to skip non-json lines? #884

Closed
luckydonald opened this issue Aug 6, 2015 · 14 comments
Closed

How to skip non-json lines? #884

luckydonald opened this issue Aug 6, 2015 · 14 comments
Labels

Comments

@luckydonald
Copy link

The situation:
I am getting input, piped in from another program.
Sometimes there are error messages, which are no valid json.
The next line there will be valid json (or another error) again.
So how can I say "discard the line (ending with \n) and continue with the next one"?

Example how piped input looks like:

Program started...
{"example":{"valid-json": true}}
ERROR LOL
{"valid-json": "yes, it is.","parse me": ["please", "i beg you"]}
["sometimes", "I", "get", "lists", "too"]

How can I ignore all lines which

failes to parse?
The closest I got was
.|split("\n")[]| fromjson.example with Raw Input enabled.
It at least processed all lines, and only raises errors on the non-json lines.
Still I don't found a way how to surpress the errors, and get the correct lines printed again.
screenshot

@luckydonald
Copy link
Author

Ugly workaround, grep to use only lines starting with "{":

the_executable | grep '^{' | jq '.'

@dtolnay
Copy link
Member

dtolnay commented Aug 6, 2015

the_executable | jq -R 'fromjson?'

@dtolnay dtolnay added the support label Aug 6, 2015
@dtolnay
Copy link
Member

dtolnay commented Aug 6, 2015

You can skip non-objects with:

the_executable | jq -R 'fromjson? | select(type == "object")'

@luckydonald
Copy link
Author

dhcp232-052:.Trash luckydonald$ cat cli_temp.txt | jq -R 'fromjson? | select(type == "object")'

error: syntax error, unexpected '?', expecting $end
fromjson? | select(type == "object")        1 compile error

Latest version from homebrew (jq-1.4)

@luckydonald
Copy link
Author

Also I realized, (in case of grep) it will only output, after the executable is terminated, while grep displayes instantly.

@dtolnay
Copy link
Member

dtolnay commented Aug 6, 2015

Ah it looks like ? was added just barely after the release of 1.4 in 7fce342 and 7d3a44a. Do you want to try jq-1.5rc2 which came out a week ago? brew install jq --devel

@pkoppstein
Copy link
Contributor

@luckydonald wrote:

Ugly workaround ...

Perhaps in your case using "?" or a simple grep to select JSON entities will work, but both approaches are somewhat brittle in that they will only work reliably if every JSON entity is on a line by itself.

If on the other hand that assumption cannot be made, then focusing on weeding out the error messages might well be the way to go. The key here is that newlines are not allowed inside JSON strings. This makes it quite likely that "grep -v" will be your friend.

@dtolnay dtolnay closed this as completed Aug 8, 2015
@luckydonald
Copy link
Author

Version from brew install jq --devel works fine, thanks.

@chesshacker
Copy link

FWIW, I came up with this to display pretty JSON lines mixed with regular text lines:

the_executable | jq -R -r '. as $line | try fromjson catch $line'

@pkoppstein
Copy link
Contributor

@chesshacker - Nice example. As far as the documentation is concerned, the use of try/catch in this context is already documented in the FAQ (https://github.com/stedolan/jq/wiki/FAQ) -- search for try/catch

@DaPutzy
Copy link

DaPutzy commented Jan 29, 2019

Also I realized, (in case of grep) it will only output, after the executable is terminated, while grep displayes instantly.

@luckydonald You need to use grep with --line-buffered if you pipe it into sth else, see: https://stackoverflow.com/a/37034112

@acheronfail
Copy link

If it's any help, this function works wonders for me:

# Use `jq` with both JSON and non-JSON lines.
function jjq {
    jq -R -r "${1:-.} as \$line | try fromjson catch \$line"
}

@skylarmb
Copy link

skylarmb commented Nov 8, 2022

I took a simpler approach and just filtered bad lines out with grep

cat logfile | grep -e "^\[" -e "^{" | jq

@johnb85022
Copy link

Sed helped me, ansible facts input example, not same as the input talked about here, but is a good example.
ansible localhost -m setup -a "filter=date" |sed '1c {'|jq '.ansible_facts.ansible_date_time.weekday'''
and
ansible localhost -m setup -a "filter=date" | sed '1 s/^.*$/{/' |jq '.ansible_facts.ansible_date_time.weekday'

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

8 participants