4

Я хочу завершить сборку, если дерево каталогов содержит файл JSON, который является недопустимым в соответствии с пакетом jsonlint из NPM.

Я думал, что это будет так же просто, как запустить:

find . -name \*.json | xargs jsonlint -q

Я знал, что у меня был плохо сформированный документ JSON на диске, и это не подхватывает его.

Дальнейшие исследования показывают, что команда find работает, как и ожидалось, однако исполняемый файл jsonlint вызывается только один раз (и первый файл JSON верен).

Есть ли лучший способ сделать это, или мне нужно кое-что узнать о xargs здесь?

Я использую Ubuntu 13.10 Server и могу устанавливать пакеты при необходимости.

3 ответа3

5

Похоже, jsonlint не может работать с несколькими файлами:

$ jsonlint -h

Usage: jsonlint [file] [options]

file     file to parse; otherwise uses stdin

Обратите внимание, что это всегда говорит файл, а не файлы. Когда вы запустите команду и передадите ее вывод в xargs как вы это сделали, xargs просто объединит все выходные данные команды и передаст ее в качестве входных данных тому, что вы сказали ей выполнить. Например:

$ printf "foo\nbar\nbaz\n"
foo
bar
baz
$ printf "foo\nbar\nbaz\n" | xargs echo
foo bar baz

Это показывает, что команда, выполненная xargs была

echo foo bar baz

В случае с jsonlint вы должны сделать не jsonlint -q foo bar baz а

$ jsonlint -q foo
$ jsonlint -q bar
$ jsonlint -q baz

Самый простой способ сделать это - использовать команду find предложенную @ fede.evol:

$ find . -name \*.json -exec xargs jsonlint -q {} \;

Чтобы сделать это с помощью xargs вам нужно использовать флаг -I :

   -I replace-str
          Replace occurrences of replace-str in the initial-arguments with
          names read from standard input.  Also, unquoted  blanks  do  not
          terminate  input  items;  instead  the  separator is the newline
          character.  Implies -x and -L 1.

Например:

$ find . -name \*.json  | xargs -I {} jsonlint -q {}

Или для безопасного обращения со странными именами (например, с символами новой строки):

$ find . -name \*.json -print0  | xargs -0I {} jsonlint -q '{}'
1

Текущие ответы на этот вопрос являются неполными, поскольку предлагаемые команды не будут печатать имя неверного файла. Кроме того, jsonlint - чертовски медленный инструмент.

Вот гораздо более быстрая альтернатива, которая не требует дополнительных установок на большинстве систем:

find . -name \*.json -exec echo {} \; -exec python -mjson.tool "{}" \; 2>&1 | grep "No JSON" -B 1

1

Используйте параметр «-exec» для выполнения каждого повторения поиска. Файл повторения передается как {} и используется \; закончить команду.

Так что-то вроде:

find . -name \*.json -exec jsonlint {} \;

На выходе вы можете сделать обратный grep ": ok". что-то вроде:

find . -name "*.txt" -exec jsonlint -v {} \; 2>&1 | grep -q -v  ": ok"

Это вернет false, если есть один не в порядке или true, если есть. 2> & 1 некрасиво, но ошибки записываются в stderr по крайней мере в моей версии jsonlint

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .