如果目录树包含根据以下规则无效的 JSON 文件,则我希望构建失败:jsonlint
来自 NPM 的包。
我以为这会像跑步一样简单:
find . -name \*.json | xargs jsonlint -q
我知道磁盘上有一个格式错误的 JSON 文档,但这个功能却无法发现它。
进一步调查表明,该find
命令按预期工作,但是jsonlint
可执行文件仅被调用一次(并且第一个 JSON 文件是正确的。)
有没有更好的方法来做到这一点,或者我需要在xargs
这里学习一些东西?
我正在运行 Ubuntu 13.10 Server,如果需要的话可以安装软件包。
答案1
看起来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 '{}'
答案2
目前对这个问题的回答并不完整,因为建议的命令不会打印无效文件的名称。另外,jsonlint是一个非常慢的工具。
这是一个很多很多更快的替代方案,在大多数系统上不需要额外的安装:
find . -name \*.json -exec echo {} \; -exec python -mjson.tool "{}" \; 2>&1 | grep "No JSON" -B 1
答案3
使用“-exec”选项在每次查找重复时执行。重复文件作为 {} 传递,并使用 \; 结束命令。
因此类似于:
find . -name \*.json -exec jsonlint {} \;
在输出中,你可以对“:ok”进行逆向 grep。例如:
find . -name "*.txt" -exec jsonlint -v {} \; 2>&1 | grep -q -v ": ok"
如果有一个不正确,则返回 false;如果有一个不正确,则返回 true。2>&1 很丑陋,但至少在我的 jsonlint 版本中,错误会写入 stderr
答案4
我最近还想发现并检查我的所有 JSON 文件(同时忽略特定目录)。我找不到我想要的工具,所以我最终制作了自己的 python 模块并将其放在 pypi 上:https://pypi.org/project/JsonFNL/。