Luo*_*Son 3 grep awk quoting jq
基本上我有一个 file.log 如下
blah blah
blah blah
Hello world | {"foo": "bar"}
blah blah
Hello earth | {"foo1": "bar1"}
Run Code Online (Sandbox Code Playgroud)
现在我的目标是编写一些 shell 命令来获得如下输出:
Hello earth | "bar"
Hello earth | "bar1"
Run Code Online (Sandbox Code Playgroud)
目前这是我所拥有的:
grep Hello file.log | awk -F "|" '{print $1, system("jq " $2)}'
Run Code Online (Sandbox Code Playgroud)
但是调用 jq 给了我这个错误:
jq: error: syntax error, unexpected ':', expecting $end (Unix shell quoting issues?) at <top-level>, line 1:
bin:application
jq: 1 compile error
Run Code Online (Sandbox Code Playgroud)
我想是因为在 system() 里面,我的 $12 被去掉了所有的引号字符 (") 因此 JQ 无法识别它的 json。有什么建议吗?
system
不返回要打印的内容,它返回您执行的命令的退出值(如果一切正常,则为 0)。您将看到您的 JSON 解码数据,然后是一行Hello earth 0
jq {foo: bar}
(两个参数,不再引用 JSON)$2
包含特殊字符,如$
,您的外壳将解释它们jq
也不会这样调用,它需要一个过滤器作为第一个参数(比如“ .
”),并且它需要从文件或标准输入中读取 JSON 输入$2
是; rm -rf ~
?)。如果可以,最好避免它。撇开安全问题不谈,这里是一个awk
大部分时间都可以工作的代码:
awk -F "|" '{ printf "%s", $1; system("echo \x27" $2 "\x27 | jq .")}'
Run Code Online (Sandbox Code Playgroud)
它的作用是将$2
括在单引号 ( \x27
) 中的内容发送jq
到标准输入。
$2
包含单引号,它将破坏整个命令$2
以破折号开头(不太可能),它将被解释为一个选项echo
(我们可以使用printf
命令而不是echo
)$2
包含...'; rm -r ~; : ' ...
字符串中的任何位置)awk
代码awk -F "|" '{ printf "%s", $1; print $2 | "jq ."; close("jq ."); }'
Run Code Online (Sandbox Code Playgroud)
由于通过 stdin$2
发送到jq
进程,但现在使用awk
管道,它不再被 shell 解释,解决了上述所有问题。该jq
命令必须在每一行关闭(终止),因此调用close()
.