我正在尝试这两种变体:
cat /var/log/zwave.log | xargs -n1 jq '.'
&:
</var/log/zwave.log xargs -n1 jq '.'
似乎这两个命令都运行,但它尝试将该行作为文件位置打开。这对于我列出的第二个命令是有意义的,但对于第一个使用管道的命令,它不应该表现得好像每行都通过zwave.log
管道连接到jq '.'
吗?
我正在处理但无法控制生成的日志系统在日志文件的每一行上创建一个 json 对象:
{ "name": "PeriodicWork", "hostname": "myHost", "pid": 12189.20, "level": 20, "msg": "Executing [CheckFailedTask NodeId=8]", "time": "2017-12-04T00:20:30.953Z", "v": 0 }
但记录器偶尔会失败并产生类似的内容Unable to start service: [TimeoutError: operation timed out]
。
这就是为什么我不能只jq
在文件上使用。
答案1
不要使用 xargs。
jq '.' /var/log/zwave.log
如果只需要过滤掉json行,可以在前面使用grep
grep -E "^{" test.txt | jq '.'
Xargs 用于将其输入的每个单词作为参数附加到给定命令;使用-n 1
,它基本上相当于运行:
jq '.' "$word1"
jq '.' "$word2"
jq '.' "$word3"
这就是你所看到的。当文件包含要传递给命令的其他文件或参数的列表时,您应该使用 xargs。
¹ 表示以xargs
空格分隔的单词(至少是空格、制表符和换行符、YMMV,具体取决于语言环境和xargs
实现),但xargs
也理解某种形式的引用,尽管与现代 shell 或 JSON 文件格式不同。
答案2
如果你的文件实际上只是逐行的 json,这对于 jq 来说是微不足道的
jq 内置了对此的支持-s
cat my_file | grep -E "^{" test.txt | jq -sre '.'
这会将所有 json 连接到 jq 中的 1 个数组中,因此您必须记住这一点,但为了给您一个想法,您可以这样做
cat my_file | grep -E "^{" test.txt |jq -sre '.[].name'
这将为您转储所有名称