Home > Mobile >  Can you separate distinct JSON attributes into two files using jq?
Can you separate distinct JSON attributes into two files using jq?

Time:01-13

I am following this tutorial from Vault about creating your own certificate authority. I'd like to separate the response (change the output to API call using cURL to see the response) into two distinct files, one file possessing the certificate and issuing_ca attributes, the other file containing the private_key. The tutorial is using jq to parse JSON objects, but my unfamiliarity with jq isn't helpful here, and most searches are returning info on how to merge JSON using jq.

I've tried running something like

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 

or

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 

but no dice.

CodePudding user response:

It is not an issue with jq invocation, but the way the output files get written. Per your usage indicated, after writing the file test.cert.pem, the contents over the read end of the pipe (JSON output) is no longer available to extract the private_key contents.

To duplicate the contents over at the write end of pipe, use tee along with process substitution. The following should work on bash/zsh or ksh93 and not on 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

See this in action

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

and now observe the contents of both the files.

CodePudding user response:

You could abuse jq's ability to write to standard error (version 1.6 or later) separately from standard output.

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 
  • Related