可以使用jq将不同的JSON属性分离到两个文件中吗?

um6iljoc  于 2023-01-14  发布在  其他
关注(0)|答案(3)|浏览(129)

我正在学习Vault中有关创建自己的证书颁发机构的教程。我想将响应(使用cURL将输出更改为API调用以查看响应)转换为两个不同的文件,一个文件拥有certificateissuing_ca属性,另一个文件包含private_key。但是我对jq的不熟悉在这里没有帮助,大多数搜索都返回如何使用jq合并JSON的信息。
我试过运行类似

vault write -format=json pki_int/issue/example-dot-com \                                                            
common_name="test.example.com" \    
ttl="24h" \                 
format=pem \
jq -r '.data.certificate, .data.issuing_ca > test.cert.pem \
jq -r '.data.private_key' > test.key.pem

vault write -format=json pki_int/issue/example-dot-com \                                                            
common_name="test.example.com" \    
ttl="24h" \                 
format=pem \
| jq -r '.data.certificate, .data.issuing_ca > test.cert.pem \
| jq -r '.data.private_key' > test.key.pem

但没成功。

1l5u6lss

1l5u6lss1#

这不是jq调用的问题,而是输出文件的写入方式的问题。根据您的使用说明,在写入文件test.cert.pem后,管道读取端的内容(JSON输出)不再可用于提取private_key内容。
要在管道的写入端复制内容,请使用tee沿着进程替换。下面的代码适用于bash/zsh或ksh 93,但不适用于POSIX bourne shell sh

vault write -format=json pki_int/issue/example-dot-com \                                                            
common_name="test.example.com" \    
ttl="24h" \                 
format=pem \
| tee >( jq -r '.data.certificate, .data.issuing_ca' > test.cert.pem) \
>(jq -r '.data.private_key' > test.key.pem) \
>/dev/null

查看实际应用

jq -n '{data:{certificate: "foo", issuing_ca: "bar", private_key: "zoo"}}' \
| tee >( jq -r '.data.certificate, .data.issuing_ca' > test.cert.pem) \
>(jq -r '.data.private_key' > test.key.pem) \
>/dev/null

现在观察两个文件的内容。

fslejnso

fslejnso2#

您可能会滥用jq将标准错误(1. 6版或更高版本)与标准输出分开写入的功能。

vault write -format=json pki_int/issue/example-dot-com \                                                            
common_name="test.example.com" \    
ttl="24h" \                 
format=pem \
| jq -r '.data as $f | ($f.private_key | stderr) | ($f.certificate, $f.issuing_ca)' > test.cert.pem 2> test.key.pem
nlejzf6q

nlejzf6q3#

对于这类问题,有一种通用的技术值得一提,因为它的先决条件最少(只有jq和awk),而且它可以很好地随文件数量的增加而扩展,此外,它非常高效,因为只需要调用jq和awk中的每一个,其思想是建立一个如下形式的管道:吉|鹰...
该技术有许多变体,但在本案例中,以下变体就足够了:

jq -rc '
 .data
 | "test.cert.pem",
      "\t\(.certificate)",
      "\t\(.issuing_ca)", 
   "test.key.pem",
      "\t\(.private_key)"
' | awk -F\\t 'NF == 1 {fn=$1; next} {print $2 > fn}'

请注意,即使感兴趣的项是带有嵌入式制表符的字符串,这也是有效的。

相关问题