Проверка файлов JSON в Ubuntu из командной строки

Я ищу автономную программу командной строки, которая может проверять файлы JSON в Ubuntu: у меня есть папка, содержащая список файлов JSON, некоторые из которых, возможно, повреждены, поэтому мне нужен список поврежденных файлов JSON.

Вы случайно не используете PHP на этой машине с Ubuntu? Если это так, и вы хотите только отделить зерна от плевел: for json in folder/*; do echo $json; php -r "\$foo=json_decode(file_get_contents('$json'));"; doneэто будет отображать все имена файлов, за которыми следуют ошибки для этого файла, если они есть, - в противном случае только имя файла. Отрегулируйте для совершенства: for json in folder/*; do php -r "if ( ! \$foo=json_decode(file_get_contents('$json')) ) echo \"$json has errors\n\";"; done, в котором будут перечислены только поврежденные файлы.
@Izzy Спасибо, я запускаю PHP на какой-то машине, так что это тоже работает :) Вы можете опубликовать это как ответ.
Готово, Франк, включая объяснение для тех, кто не разбирается в технологиях и все еще хочет попробовать :) Наслаждайтесь!

Ответы (2)

Без необходимости в конкретном приложении, если вы просто хотите отделить зерна от плевел и установить PHP на машину с Linux, вы можете использовать для этого простой однострочный код:

for json in folder/*; do php -r "if ( ! \$foo=json_decode(file_get_contents('$json')) ) echo \"$json\n\";"; done

Это выведет список всех сломанных .json файлов в каталоге с именем folder. Уберите восклицательный знак ( !), чтобы перечислить только те .jsonфайлы, которые в порядке.

Вполне возможно, что PHP выдает здесь дополнительное сообщение об ошибке. Если это произойдет, просто перенаправьте вывод ошибки (STDERR) в черную дыру машины ( /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 — краткое объяснение того, что делает эта строчка

  • for json in folder/*; do […] done: цикл по всем .jsonфайлам в заданном месте. На каждой итерации сохраняйте имя файла в переменной с именем $json.
  • php -r: вызвать исполняемый файл PHP. Параметр -rговорит ему (r) запустить команду вместо ожидания файла. Команда должна следовать непосредственно за этим, разделенным пробелом.
  • "[…]": использование двойных кавычек упрощает интеграцию переменных оболочки. Цена в том, что мы должны избегать всех $знаков, принадлежащих переменным PHP.
  • \$foo: см. предыдущий пункт, нам нужно выйти из $здесь.
  • $foo=json_decode(file_get_contents('$json')): пусть PHP читает файл ( file_get_contents; $jsonэто наша переменная Bash из первого пункта), затем конвертирует JSON в объект PHP ( json_decode). Мы не хотим видеть результат, поэтому присваиваем его переменной ( $fooв моем примере).
    Если декодирование прошло успешно, то присваивание вернет TRUE, иначе FALSE— именно поэтому мы можем использовать эту конструкцию как наше «условие if».
  • if ( […] ) echo \"$json\n\";": только записывайте имя файла (здесь это снова наша переменная Bash) в консоль, если выполняется наше условие — «отделить зерна от плевел», как я выразился изначально. Как обычно в PHP, команда должна заканчиваться точкой с запятой ( ;). Также обратите внимание, что здесь мне нужно было избежать двойных кавычек, чтобы наша «внешняя оболочка оболочки» не заканчивалась преждевременно. Мне нужны двойные кавычки, поэтому это интерпретируется как «новая строка» — с одинарными кавычками вместо \nэтого будет напечатан литерал .\n
  • 2>/dev/null: перенаправить вывод ошибок (STDERR) в «черную дыру» (т. е. не показывать никаких ошибок, если они происходят). Наши echoкоманды идут в STDOUT и, следовательно, не затрагиваются этим.

Вы можете использовать jsonlint :

  • CLI
  • с открытым исходным кодом (написано на JavaScript)
  • проверьте, являются ли файлы действительными:

Пример:

# 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$

Полезные опции:

   -c, --compact            compact error display
   -V, --validate           a JSON schema to use for validation