I have yet to find a system where python -mjson.tool doesn't work. So you can do:
python -mjson.tool "$somefile" > /dev/null
The exit code will be nonzero and you get the parse error on stderr if the file is not valid JSON.
Note: The Python libraries don't follow the JSON spec and allow NaN and Infinity as values. So using json.tool will let some errors slip through. Still it's good enough for my use case of catching errors in human-written documents early.
I have yet to find a system where python -mjson.tool doesn't work. So you can do:
python -mjson.tool "$somefile" > /dev/null
The exit code will be nonzero and you get the parse error on stderr if the file is not valid JSON.
Note: The Python libraries don't follow the JSON spec and allow NaN and Infinity as values. So using json.tool will let some errors slip through. Still it's good enough for my use case of catching errors in human-written documents early.
The very simplest way is using json_pp (json pretty print) from perl.
$ echo {} | json_pp
{}
$ echo [] | json_pp
[]
$ echo 5 | json_pp
5
$ echo a | json_pp
malformed JSON string, neither array, object, number, string or atom, at character offset 0 (before "a\n") at /usr/bin/json_pp line 59.
For file you can do
$ cat file.json | json_pp
For more info
$ man json_pp
You can use jq and send stdout to null
sudo apt-get install jq
jq . /path/to/yourfile.json 1> /dev/null
Example Execution
Here's some example runs
No Errors
If there are no errors in the json file, then there will be no output and the exit code is 0
user@host:~$ jq . updates/v1/meta.json 1> /dev/null
user@host:~$ echo $?
0
user@host:~$
Errors
If there are errors in the json file, then the output will tell you exactly which line & character, and the exit code will be non-zero
user@host:~$ jq . updates/v1/meta.json 1> /dev/null
parse error: Expected another array element at line 15, column 8
user@host:~$ echo $?
4
user@host:~$
sudo apt install jsonlint
and then do jsonlint-php {file}
Manual page:
OPTIONS
-q, --quiet
Cause jsonlint to be quiet when no errors are found
-h, --help
Show this message
Try jsonlint:
sudo apt install jsonlint
The basic usage syntax is
jsonlint YOUR-FILE.JSON
You find its manual by typing man jsonlint or visiting its online manpage:
An excerpt:
NAME
jsonlint - A JSON syntax validator and formatter tool
SYNOPSIS
jsonlint [-v][-s|-S][-f|-F][-ecodec]inputfile.json...
[...]
OPTIONS
The return status will be 0 if the file is legal JSON, or non-zero
otherwise. Use -v to see the warning details.
[...]
-v, --verbose
Show details of lint checking
-s, --strict
Be strict in what is considered legal JSON (the default)
-S, --nonstrict
Be loose in what is considered legal JSON
-f, --format
Reformat the JSON (if legal) to stdout
[...]
So you can see whether your JSON is valid by checking the return code of jsonlint. You can see it by running echo $? right afterwards (0=OK, 1=invalid), or by evaluating it using &&, || or if.
I tried jsonlint but it doesn't work.
jq . may-file.json work nice!
Hope this feedback is helpful.
Without the need for a specific application, if you just want to separate the wheat from the chaff, and have PHP installed on the Linux machine, you can use a simple one-liner for this:
for json in folder/*; do php -r "if ( ! \$foo=json_decode(file_get_contents('$json')) ) echo \"$json\n\";"; done
This would list all broken .json files in the directory named folder. Take out the exlamation mark (!) to only list the .json files which are fine.
It might well be PHP spits out some additional error message here. If that happens, just re-direct error output (STDERR) to the machine's black hole (/dev/null):
for json in folder/*; do php -r "if ( ! \$foo=json_decode(file_get_contents('$json')) ) echo \"$json\n\";" 2>/dev/null; done
TL;DR – a short explanation of what that one-liner does
for json in folder/*; do […] done: loop over all.jsonfiles in the given location. On each iteration, store the file name into a variable named$json.php -r: invoke the PHP executable. The-rparameter tells it to (r)un a command instead of expecting a file. The command must directly follow this, separated by white-space."[…]": using double-quotes, we can easier integrate shell variables. The price is we have to escape all$signs belonging to PHP variables.\$foo: see previous point, we need to escape the$here.$foo=json_decode(file_get_contents('$json')): have PHP reading the file (file_get_contents; the$jsonhere is our Bash variable from the first bullet-point), then convert the JSON to a PHP object (json_decode). We don't want to see the result, so we assign it to a variable ($fooin my example).
If decoding was successful, the assignment will returnTRUE, otherwiseFALSE– which is why we can use this construction as our "if condition".if ( […] ) echo \"$json\n\";": only write the file name (this again is our Bash variable here) to the console if our condition is met – to "separate the wheat from the chaff", as I've put it initially. As usual in PHP, the command needs to be terminated by a semi-colon (;). Also note that I needed to escape the double-quotes here, so our "outer Shell wrapper" doesn't end prematurely. I needed the double-quotes, so\nis interpreted as "new line" – with single-quotes, it would print a literal\ninstead.2>/dev/null: Redirect error output (STDERR) to the "black hole" (i.e. don't show any errors if they occur). Ourechocommands go to STDOUT, and thus are not affected by this.
You can use jsonlint:
- CLI
- open source (written in JavaScript)
- check whether file(s) are valid:
Example:
# Install
sudo apt-get install -y nodejs npm
sudo npm install jsonlint -g
sudo ln -s /usr/bin/nodejs /usr/bin/node # to avoid "/usr/bin/env: node: No such file or directory" error
jsonlint -qc *.json
# Use
ubuntu@pm:~/pubmed/pubmed$ jsonlint --compact --validate *.json
my_file_bad.json: line 279916, col 18, found: 'EOF' - expected: 'STRING', 'NUMBER', 'NULL', 'TRUE', 'FALSE', '{', '['.
ubuntu@pm:~/pubmed/pubmed$
Useful options:
-c, --compact compact error display
-V, --validate a JSON schema to use for validation