<?xml version="1.0" encoding="UTF-8"?><feed xmlns="http://www.w3.org/2005/Atom"><id>https://vic.demuzere.be/articles/tags/jq/atom.xml</id><title>Vic Demuzere - jq</title><link href="https://vic.demuzere.be/articles/tags/jq/atom.xml" rel="self" type="application/atom+xml" /><link href="https://vic.demuzere.be/articles/tags/jq/" rel="alternate" type="text/html" /><updated>2021-02-10T20:01:03+00:00</updated><author><name>Vic Demuzere</name></author><entry><id>https://vic.demuzere.be/articles/using-bash-variables-in-jq/</id><title>Using bash variables in jq</title><link href="https://vic.demuzere.be/articles/using-bash-variables-in-jq/" rel="alternate" /><updated>2024-11-11T18:21:44+00:00</updated><published>2021-02-10T20:01:03+00:00</published><content type="html"><![CDATA[<p>Due to the special characters used in json, the easiest way to use jq with inline scripts it by putting it between single quotes.
That <strong>makes it impossible to use bash variables inside your script</strong>.
Fortunately, jq has an <code>--arg</code> parameter to create a predefined variable from an external source.</p>
<p>You can use it to define a <code>$foo</code> variable with the contents of bash variable <code>$FOO</code>, for example:</p>
<pre><code>$ export FOO=&quot;bar&quot;
$ jq -n --arg foo &quot;$FOO&quot; '{foo: $foo}'
{
  &quot;foo&quot;: &quot;bar&quot;
}
</code></pre>
<p>You might notice the <code>-n</code> parameter: This tells <code>jq</code> to use <code>null</code> as input instead of reading json from stdin like it normally would.
I'm using it in all examples on this page as it makes them a bit shorter.
In real world usage, you probably won't need it.</p>
<p>As usual in bash scripts, you can also execute a command inline:</p>
<pre><code>$ jq -n --arg hostname &quot;$(hostname)&quot; '{foo: $hostname}'
{
  &quot;foo&quot;: &quot;cypher&quot;
}
</code></pre>
<p>Every variable created with <code>--arg</code> is <strong>treated as a string</strong>.
That might cause some unexpected behavior when you work with numbers, like when you attempt to add a number to an argument.
Comparisons between strings and numbers seem to work fine, but I wouldn't count on it (pun intended).</p>
<pre><code>$ echo '{&quot;a&quot;: 3.0}' | jq --arg foo 5 '$foo + .a'
jq: error (at &lt;stdin&gt;:1): string (&quot;5&quot;) and number (3) cannot be added
</code></pre>
<p>There are two ways to solve this: either convert the variable to a number with <code>tonumber</code> or use <code>--argjson</code> instead.
I prefer to use <code>tonumber</code> because that way I'm sure jq forces it to be a number.
As my argument may be the result of an earlier command, I may be using an error message as input instead of the expected numeric result.</p>
<pre><code>$ jq -n --arg foo 5 '($foo|tonumber) + 1'
6

$ jq -n --argjson foo 5 '$foo + 1'
6
</code></pre>
<h2 id="variables-from-files">Variables from files<a href="#variables-from-files" aria-label="Link to heading 'Variables from files'" data-heading-content="Variables from files" class="anchor"></a></h2>
<p>It's also possible to load variables from files.
With <code>--slurpfile</code> we can read a file containing json objects.
An array containing the separate objects is then made available as a predefined variable.
Note that even if your file contains only a single json object, as the variable is still an array, the <code>[0]</code> is required to access it.</p>
<pre><code>$ cat foo.json
{&quot;foo&quot;: &quot;bar&quot;}
{&quot;bar&quot;: &quot;foo&quot;}

$ jq -n --slurpfile foo foo.json '$foo[0].foo'
&quot;bar&quot;
</code></pre>
<p>A second option is <code>--rawfile</code>, creating a string variable with the exact contents of the file.
Note that as jq outputs json, reading and printing the file from the previous example results an escaped string.</p>
<pre><code>$ jq -n --rawfile foo foo.json '$foo'
&quot;{\&quot;foo\&quot;: \&quot;bar\&quot;}\n{\&quot;bar\&quot;: \&quot;foo\&quot;}\n&quot;
</code></pre>
<p>That's it!</p>
<div class="footer"><hr><p>Thanks for subscribing to my feed!</p><p>Feel free to e-mail comments or corrections to <a href="mailto:vic@demuzere.be?subject=RE%3A%20Using%20bash%20variables%20in%20jq">vic@demuzere.be</a>.</p></div>]]></content></entry></feed>