<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Kengah Ireneaus</title>
    <description>The latest articles on DEV Community by Kengah Ireneaus (@4kit1-glitch).</description>
    <link>https://dev.to/4kit1-glitch</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3775003%2Fc3d04ce3-2b37-41a3-840a-1c448d9c8313.jpg</url>
      <title>DEV Community: Kengah Ireneaus</title>
      <link>https://dev.to/4kit1-glitch</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/4kit1-glitch"/>
    <language>en</language>
    <item>
      <title>A Practical Guide to jq in Shell Scripts</title>
      <dc:creator>Kengah Ireneaus</dc:creator>
      <pubDate>Sun, 16 Aug 2026 18:01:26 +0000</pubDate>
      <link>https://dev.to/4kit1-glitch/a-practical-guide-to-jq-in-shell-scripts-dp6</link>
      <guid>https://dev.to/4kit1-glitch/a-practical-guide-to-jq-in-shell-scripts-dp6</guid>
      <description>&lt;h2&gt;
  
  
  A Practical Guide to jq in Shell Scripts
&lt;/h2&gt;

&lt;p&gt;While building &lt;code&gt;sykd&lt;/code&gt; (a system health monitor daemon for linux servers) i needed to collect system data as json so i could process easily in python on doing research if found out about the &lt;code&gt;jq shell program&lt;/code&gt; for creating and parsing json in bash, but learning the commands was quite tedious and the man page is large and very difficult to read so i came out with this guide to ease and summarize the major commands you might need.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;jq&lt;/code&gt; is a lightweight and flexible command-line JSON processor. It is one of the most useful tools for working with JSON data directly inside shell scripts and pipelines.&lt;/p&gt;

&lt;h2&gt;
  
  
  Installation
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Debian / Ubuntu&lt;/strong&gt;: &lt;code&gt;sudo apt install jq&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;macOS&lt;/strong&gt;: &lt;code&gt;brew install jq&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Other systems&lt;/strong&gt;: Use your package manager or download binaries from the official site.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Basic Usage
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;jq &lt;span class="o"&gt;[&lt;/span&gt;options] &lt;span class="s1"&gt;'&amp;lt;filter&amp;gt;'&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;file...]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Input can come from a file, a pipe, or standard input. The filter expression selects or transforms the data.&lt;/p&gt;

&lt;p&gt;Quick note: &lt;code&gt;jq&lt;/code&gt; reads JSON from stdin by default. If you want to generate JSON inside &lt;code&gt;jq&lt;/code&gt; without reading input, use &lt;code&gt;-n&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Useful Options
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Option&lt;/th&gt;
&lt;th&gt;Purpose&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;-r&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Raw output (no JSON quotes around strings)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;-c&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Compact (single-line) output&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;-n&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Start with &lt;code&gt;null&lt;/code&gt; input (useful for generating JSON)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;-s&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Slurp entire input into an array&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;--arg&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Pass a string variable&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;--argjson&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Pass a JSON value (preferred for arrays/objects)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Other helpful runtime options:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Option&lt;/th&gt;
&lt;th&gt;Purpose&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;--rawfile name filename&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Read an entire file as a raw string into variable &lt;code&gt;$name&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;--slurpfile name filename&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Read file and slurp into array &lt;code&gt;$name&lt;/code&gt; (like &lt;code&gt;-s&lt;/code&gt; but into variable)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Example: &lt;code&gt;jq --slurpfile all files.json '.[0] + $all[0]'&lt;/code&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Essential Filters
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Goal&lt;/th&gt;
&lt;th&gt;Filter Example&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Pretty-print&lt;/td&gt;
&lt;td&gt;&lt;code&gt;.&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Extract a field&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;.name&lt;/code&gt; or &lt;code&gt;.["name"]&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Nested field&lt;/td&gt;
&lt;td&gt;&lt;code&gt;.user.address.city&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Array element&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;.[0]&lt;/code&gt; or &lt;code&gt;.[-1]&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Iterate array&lt;/td&gt;
&lt;td&gt;&lt;code&gt;.[]&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Select matching objects&lt;/td&gt;
&lt;td&gt;`.[] \&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Build a new object&lt;/td&gt;
&lt;td&gt;{% raw %}&lt;code&gt;{name, age}&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Transform every element&lt;/td&gt;
&lt;td&gt;&lt;code&gt;map(.name)&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Length&lt;/td&gt;
&lt;td&gt;&lt;code&gt;length&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;List keys&lt;/td&gt;
&lt;td&gt;&lt;code&gt;keys&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Conditional&lt;/td&gt;
&lt;td&gt;&lt;code&gt;if .active then "yes" else "no" end&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;You can define reusable functions inside &lt;code&gt;jq&lt;/code&gt; using &lt;code&gt;def&lt;/code&gt;. Example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;def greet: "Hello, " + .name + "!";
. | greet
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This will output &lt;code&gt;"Hello, &amp;lt;name&amp;gt;!"&lt;/code&gt; for an object with a &lt;code&gt;name&lt;/code&gt; key.&lt;/p&gt;

&lt;h2&gt;
  
  
  Practical Examples
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Pretty-print a file&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;jq &lt;span class="nb"&gt;.&lt;/span&gt; data.json
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Extract a single value&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;jq &lt;span class="nt"&gt;-r&lt;/span&gt; &lt;span class="s1"&gt;'.version'&lt;/span&gt; package.json
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Filter an array of objects&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;jq &lt;span class="s1"&gt;'.[] | select(.status == "active") | .name'&lt;/span&gt; users.json
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Create a new structure&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;jq &lt;span class="s1"&gt;'{names: map(.name), total: length}'&lt;/span&gt; people.json
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Use in a pipeline&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-s&lt;/span&gt; https://api.example.com/data | jq &lt;span class="s1"&gt;'.results[] | .id'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Generate JSON from scratch&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;jq &lt;span class="nt"&gt;-n&lt;/span&gt; &lt;span class="s1"&gt;'{name: "example", version: 1}'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Create multiple objects programmatically&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;jq &lt;span class="nt"&gt;-n&lt;/span&gt; &lt;span class="s1"&gt;'[range(3) | {index: ., squared: (. * .)}]'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This produces:&lt;/p&gt;

&lt;p&gt;[&lt;br&gt;
   {"index":0,"squared":0},&lt;br&gt;
   {"index":1,"squared":1},&lt;br&gt;
   {"index":2,"squared":4}&lt;br&gt;
]&lt;/p&gt;
&lt;h2&gt;
  
  
  Passing a Bash Array to jq
&lt;/h2&gt;

&lt;p&gt;Bash arrays cannot be passed directly. Convert the array to a JSON array first, then supply it with &lt;code&gt;--argjson&lt;/code&gt;.&lt;/p&gt;
&lt;h3&gt;
  
  
  Recommended Method
&lt;/h3&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;my_array&lt;/span&gt;&lt;span class="o"&gt;=(&lt;/span&gt;&lt;span class="s2"&gt;"apple"&lt;/span&gt; &lt;span class="s2"&gt;"banana"&lt;/span&gt; &lt;span class="s2"&gt;"cherry"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;

&lt;span class="c"&gt;# Convert bash array → JSON array&lt;/span&gt;
&lt;span class="nv"&gt;json_array&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;printf&lt;/span&gt; &lt;span class="s1"&gt;'%s\n'&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;my_array&lt;/span&gt;&lt;span class="p"&gt;[@]&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; | jq &lt;span class="nt"&gt;-R&lt;/span&gt; &lt;span class="nb"&gt;.&lt;/span&gt; | jq &lt;span class="nt"&gt;-s&lt;/span&gt; .&lt;span class="si"&gt;)&lt;/span&gt;

&lt;span class="c"&gt;# Use it inside jq&lt;/span&gt;
jq &lt;span class="nt"&gt;--argjson&lt;/span&gt; arr &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$json_array&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="s1"&gt;'$arr'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;One-liner version:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;jq &lt;span class="nt"&gt;--argjson&lt;/span&gt; arr &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;printf&lt;/span&gt; &lt;span class="s1"&gt;'%s\n'&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;my_array&lt;/span&gt;&lt;span class="p"&gt;[@]&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; | jq &lt;span class="nt"&gt;-R&lt;/span&gt; &lt;span class="nb"&gt;.&lt;/span&gt; | jq &lt;span class="nt"&gt;-s&lt;/span&gt; .&lt;span class="si"&gt;)&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
   &lt;span class="s1"&gt;'$arr[]'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Numeric Arrays
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;numbers&lt;/span&gt;&lt;span class="o"&gt;=(&lt;/span&gt;10 20 30&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="nv"&gt;json_numbers&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;printf&lt;/span&gt; &lt;span class="s1"&gt;'%s\n'&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;numbers&lt;/span&gt;&lt;span class="p"&gt;[@]&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; | jq &lt;span class="nt"&gt;-s&lt;/span&gt; .&lt;span class="si"&gt;)&lt;/span&gt;

jq &lt;span class="nt"&gt;--argjson&lt;/span&gt; nums &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$json_numbers&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="s1"&gt;'$nums | map(. * 2)'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Feed as Input Instead
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;printf&lt;/span&gt; &lt;span class="s1"&gt;'%s\n'&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;my_array&lt;/span&gt;&lt;span class="p"&gt;[@]&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; | jq &lt;span class="nt"&gt;-R&lt;/span&gt; &lt;span class="nb"&gt;.&lt;/span&gt; | jq &lt;span class="nt"&gt;-s&lt;/span&gt; &lt;span class="nb"&gt;.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Tips for Reliable Shell Scripts
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Always quote the filter when it contains spaces or special characters.&lt;/li&gt;
&lt;li&gt;Prefer &lt;code&gt;--argjson&lt;/code&gt; for arrays and objects; use &lt;code&gt;--arg&lt;/code&gt; only for plain strings.&lt;/li&gt;
&lt;li&gt;Test filters interactively before embedding them in scripts.&lt;/li&gt;
&lt;li&gt;&lt;p&gt;For complex logic, store the filter in a separate &lt;code&gt;.jq&lt;/code&gt; file and call it with &lt;code&gt;-f&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;When embedding multi-line filters in shell variables, use a heredoc to keep quoting simple:&lt;br&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;filter&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;cat&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="no"&gt;EOF&lt;/span&gt;&lt;span class="sh"&gt;'
.[] | select(.status=="active") | {id, name}
&lt;/span&gt;&lt;span class="no"&gt;EOF
&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;

curl &lt;span class="nt"&gt;-s&lt;/span&gt; api | jq &lt;span class="nt"&gt;-f&lt;/span&gt; &amp;lt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$filter&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Prefer &lt;code&gt;--argjson&lt;/code&gt; when you need to pass non-string structured data; &lt;code&gt;--arg&lt;/code&gt; always passes a string.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;When values may contain newlines or special characters, convert them to JSON with &lt;code&gt;jq -R .&lt;/code&gt; before passing.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;For newline-delimited JSON (NDJSON/JSONL), use &lt;code&gt;jq -c .&lt;/code&gt; to ensure compact output and &lt;code&gt;--slurp&lt;/code&gt; if you need to combine records into an array.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Use &lt;code&gt;try ... catch&lt;/code&gt; for safe extraction and defaults:&lt;br&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;try .foo.bar catch "default"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Use &lt;code&gt;inputs&lt;/code&gt; to read multiple JSON documents from stdin (useful with &lt;code&gt;-n&lt;/code&gt;):
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# echo multiple JSON objects and process them with inputs&lt;/span&gt;
&lt;span class="nb"&gt;printf&lt;/span&gt; &lt;span class="s1"&gt;'%s
'&lt;/span&gt; &lt;span class="s1"&gt;'{"x":1}'&lt;/span&gt; &lt;span class="s1"&gt;'{"x":2}'&lt;/span&gt; | jq &lt;span class="nt"&gt;-n&lt;/span&gt; &lt;span class="s1"&gt;'[inputs | .x]'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Additional Examples and Patterns
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Selecting and Transforming
&lt;/h3&gt;

&lt;p&gt;Extract and rename fields:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;jq &lt;span class="s1"&gt;'.[] | {identifier: .id, user: .name, active: .status == "active"}'&lt;/span&gt; users.json
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Build an index (map id → object):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;jq &lt;span class="s1"&gt;'map({ (.id|tostring): . }) | add'&lt;/span&gt; users.json
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Group by a key and count per group:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;jq &lt;span class="s1"&gt;'group_by(.category) | map({category: .[0].category, count: length})'&lt;/span&gt; items.json
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Working with Strings
&lt;/h3&gt;

&lt;p&gt;Trim and lowercase a field:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;jq &lt;span class="s1"&gt;'.name | ascii_downcase | gsub("^ +| +$"; "")'&lt;/span&gt; person.json
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Join array of strings:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;jq &lt;span class="nt"&gt;-r&lt;/span&gt; &lt;span class="s1"&gt;'.tags | join(",")'&lt;/span&gt; article.json
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Numeric operations
&lt;/h3&gt;

&lt;p&gt;Sum field values:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;jq &lt;span class="s1"&gt;'[.[] | .size] | add'&lt;/span&gt; files.json
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Find maximum:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;jq &lt;span class="s1"&gt;'max_by(.score) | .score'&lt;/span&gt; scores.json
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Advanced: reduce, recurse, and more
&lt;/h3&gt;

&lt;p&gt;Use &lt;code&gt;reduce&lt;/code&gt; to accumulate values:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;jq &lt;span class="s1"&gt;'reduce .[] as $item (0; . + $item.value)'&lt;/span&gt; metrics.json
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Recursively find all keys named &lt;code&gt;id&lt;/code&gt; in nested structure:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;jq &lt;span class="s1"&gt;'.. | objects | .id? // empty'&lt;/span&gt; nested.json
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Streaming large JSON (&lt;code&gt;jq --stream&lt;/code&gt;)
&lt;/h3&gt;

&lt;p&gt;For very large JSON documents use &lt;code&gt;--stream&lt;/code&gt; to get path/value pairs; processing is more manual but uses much less memory:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;jq &lt;span class="nt"&gt;--stream&lt;/span&gt; &lt;span class="s1"&gt;'select(.[0][-1]=="targetKey") | .[1]'&lt;/span&gt; large.json
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Working with NDJSON / JSONL
&lt;/h3&gt;

&lt;p&gt;To parse newline-delimited JSON and combine into an array:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;jq &lt;span class="nt"&gt;-s&lt;/span&gt; &lt;span class="s1"&gt;'.'&lt;/span&gt; file.jsonl
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Process each line independently (streaming):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;jq &lt;span class="nt"&gt;-c&lt;/span&gt; &lt;span class="s1"&gt;'. | {id: .id, ok: (.value &amp;gt; 0)}'&lt;/span&gt; file.jsonl
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Filters in separate &lt;code&gt;.jq&lt;/code&gt; files
&lt;/h3&gt;

&lt;p&gt;Save a complex filter to &lt;code&gt;filters.jq&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;def summarize:
   {total: (map(.value) | add), count: length};

.items | map({k: .key, v: .value}) | summarize
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Call it from shell:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;jq &lt;span class="nt"&gt;-f&lt;/span&gt; filters.jq data.json
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Passing environment variables into &lt;code&gt;jq&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;Pass a shell variable as JSON (string):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"O'Reilly"&lt;/span&gt;
jq &lt;span class="nt"&gt;--arg&lt;/span&gt; name &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$name&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="s1"&gt;'. + {author: $name}'&lt;/span&gt; book.json
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Pass an environment variable that is already JSON:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;json_obj&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'{"a":1}'&lt;/span&gt;
jq &lt;span class="nt"&gt;--argjson&lt;/span&gt; o &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$json_obj&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="s1"&gt;'. + $o'&lt;/span&gt; base.json
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Error handling and safe accesses
&lt;/h3&gt;

&lt;p&gt;Use &lt;code&gt;?&lt;/code&gt; to avoid errors when a key may not exist:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;jq &lt;span class="s1"&gt;'.maybe?.nested // "default"'&lt;/span&gt; data.json
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Use &lt;code&gt;try&lt;/code&gt; to catch runtime errors:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;jq &lt;span class="s1"&gt;'try .items[] catch empty'&lt;/span&gt; data.json
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Common pitfalls
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Forgetting to quote filters when they contain shell-sensitive characters — always wrap your filter in single quotes in shell.&lt;/li&gt;
&lt;li&gt;Passing arrays with &lt;code&gt;--arg&lt;/code&gt; (creates a JSON string, not an array) — use &lt;code&gt;--argjson&lt;/code&gt; or &lt;code&gt;jq -s&lt;/code&gt; conversion.&lt;/li&gt;
&lt;li&gt;Assuming &lt;code&gt;jq&lt;/code&gt; modifies files in-place — it writes to stdout; redirect output to a file to save changes.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Performance tips
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Use &lt;code&gt;--stream&lt;/code&gt; for very large JSON that can't fit in memory.&lt;/li&gt;
&lt;li&gt;Avoid unnecessary &lt;code&gt;map&lt;/code&gt; + &lt;code&gt;add&lt;/code&gt; for simple reductions; &lt;code&gt;reduce&lt;/code&gt; can be more efficient.&lt;/li&gt;
&lt;li&gt;Use compiled filters in &lt;code&gt;-f&lt;/code&gt; files for complex repeated transformations.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Examples: Real shell script snippets
&lt;/h3&gt;

&lt;p&gt;Filter API result and extract IDs into a bash array:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;readarray &lt;span class="nt"&gt;-t&lt;/span&gt; ids &amp;lt; &amp;lt;&lt;span class="o"&gt;(&lt;/span&gt;curl &lt;span class="nt"&gt;-s&lt;/span&gt; &lt;span class="s2"&gt;"https://api.example.com/items"&lt;/span&gt; | jq &lt;span class="nt"&gt;-r&lt;/span&gt; &lt;span class="s1"&gt;'.items[].id'&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;for &lt;/span&gt;&lt;span class="nb"&gt;id &lt;/span&gt;&lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;ids&lt;/span&gt;&lt;span class="p"&gt;[@]&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;do
   &lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Got id: &lt;/span&gt;&lt;span class="nv"&gt;$id&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;span class="k"&gt;done&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Pass a bash array of words safely into &lt;code&gt;jq&lt;/code&gt; and filter by membership:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;words&lt;/span&gt;&lt;span class="o"&gt;=(&lt;/span&gt;alpha beta &lt;span class="s2"&gt;"complex value"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="nv"&gt;json_words&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;printf&lt;/span&gt; &lt;span class="s1"&gt;'%s\n'&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;words&lt;/span&gt;&lt;span class="p"&gt;[@]&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; | jq &lt;span class="nt"&gt;-R&lt;/span&gt; &lt;span class="nb"&gt;.&lt;/span&gt; | jq &lt;span class="nt"&gt;-s&lt;/span&gt; .&lt;span class="si"&gt;)&lt;/span&gt;

curl &lt;span class="nt"&gt;-s&lt;/span&gt; dataset.json | jq &lt;span class="nt"&gt;--argjson&lt;/span&gt; words &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$json_words&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="s1"&gt;'[.[] | select(.name as $n | $words | index($n))]'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Create a small portable CLI using &lt;code&gt;jq&lt;/code&gt; and &lt;code&gt;bash&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;#!/usr/bin/env bash&lt;/span&gt;
&lt;span class="nv"&gt;data_file&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;1&lt;/span&gt;&lt;span class="k"&gt;:-&lt;/span&gt;&lt;span class="nv"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.json&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;
&lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="nv"&gt;$2&lt;/span&gt; &lt;span class="k"&gt;in
   &lt;/span&gt;list&lt;span class="p"&gt;)&lt;/span&gt;
      jq &lt;span class="nt"&gt;-r&lt;/span&gt; &lt;span class="s1"&gt;'.items[] | "\(.id) - \(.name)"'&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$data_file&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="p"&gt;;;&lt;/span&gt;
   stats&lt;span class="p"&gt;)&lt;/span&gt;
      jq &lt;span class="s1"&gt;'{total: (.items | length), sum: (.items | map(.value) | add)}'&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$data_file&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="p"&gt;;;&lt;/span&gt;
   &lt;span class="k"&gt;*&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Usage: &lt;/span&gt;&lt;span class="nv"&gt;$0&lt;/span&gt;&lt;span class="s2"&gt; &amp;lt;file&amp;gt; {list|stats}"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nb"&gt;exit &lt;/span&gt;2 &lt;span class="p"&gt;;;&lt;/span&gt;
&lt;span class="k"&gt;esac&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;With a few core filters and the correct technique for passing arrays, &lt;code&gt;jq&lt;/code&gt; becomes a powerful and reliable tool inside any shell workflow. The patterns shown above cover the majority of day-to-day JSON processing needs.&lt;/p&gt;

&lt;p&gt;Happy scripting!&lt;/p&gt;

</description>
      <category>bash</category>
      <category>jq</category>
      <category>json</category>
      <category>devops</category>
    </item>
    <item>
      <title>A Month With Bash — Part 3: Building Projects</title>
      <dc:creator>Kengah Ireneaus</dc:creator>
      <pubDate>Tue, 04 Aug 2026 00:36:48 +0000</pubDate>
      <link>https://dev.to/4kit1-glitch/a-month-with-bash-part-3-building-projects-3od9</link>
      <guid>https://dev.to/4kit1-glitch/a-month-with-bash-part-3-building-projects-3od9</guid>
      <description>&lt;h2&gt;
  
  
  A Month With Bash — Part 3: Building Projects
&lt;/h2&gt;

&lt;p&gt;After all the expansions and syntax, I moved on to regex in bash. It wasn't too hard since I'd already worked with regex in Python, but alongside it I learned &lt;code&gt;grep&lt;/code&gt;, &lt;code&gt;sed&lt;/code&gt;, and &lt;code&gt;awk&lt;/code&gt; — tools that turned out to be extremely useful for automation.&lt;/p&gt;

&lt;p&gt;I built a few mini projects and started automating some of my small day-to-day tasks. I won't go too deep into that here, but you can check out my learning-bash GitHub repo, which has all my learning scripts.&lt;/p&gt;

&lt;p&gt;From there I covered conditionals, loops, and repetitive tasks.&lt;/p&gt;

&lt;h2&gt;
  
  
  Finally
&lt;/h2&gt;

&lt;p&gt;I learned about array variables in bash and shell options, &lt;br&gt;
went even further testing different ways of looping, and that's when I started actual project building(I am still building )&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;#!/usr/bin/env bash&lt;/span&gt;

&lt;span class="c"&gt;## looping with range functions -- somehow&lt;/span&gt;

&lt;span class="c"&gt;# python style looping {start..end}&lt;/span&gt;
&lt;span class="k"&gt;for &lt;/span&gt;i &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;1..10&lt;span class="o"&gt;}&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;    &lt;span class="c"&gt;# this uses brace expansion so using vars wont work becase of execution sequencing&lt;/span&gt;
    &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="nv"&gt;$i&lt;/span&gt;
&lt;span class="k"&gt;done

&lt;/span&gt;clear

&lt;span class="c"&gt;## c - slyle looping &lt;/span&gt;
&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="o"&gt;((&lt;/span&gt; i &lt;span class="o"&gt;=&lt;/span&gt; 0&lt;span class="p"&gt;;&lt;/span&gt; i &amp;lt; 10&lt;span class="p"&gt;;&lt;/span&gt; i++ &lt;span class="o"&gt;))&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="c"&gt;# variables works here well&lt;/span&gt;
    &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"hello &lt;/span&gt;&lt;span class="nv"&gt;$i&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;span class="k"&gt;done&lt;/span&gt;

&lt;span class="c"&gt;## using variables to loop&lt;/span&gt;

clear
&lt;span class="nv"&gt;start&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;1
&lt;span class="nv"&gt;stop&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;10
&lt;span class="nv"&gt;step&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;2

&lt;span class="k"&gt;for &lt;/span&gt;i &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;seq&lt;/span&gt; &lt;span class="nv"&gt;$start&lt;/span&gt; &lt;span class="nv"&gt;$stop&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="c"&gt;# this uses the seq command&lt;/span&gt;
    &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"hello world"&lt;/span&gt;
&lt;span class="k"&gt;done&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Spending so much time on bash wasn't a waste. Not only did it force me to learn a huge number of commands, it changed how I think about my own machine — most of what I used to do manually, I can now automate. That shift alone made the month worth it.&lt;br&gt;
i am still learning and trying to get the best practices and things not to do&lt;/p&gt;




&lt;p&gt;&lt;em&gt;THANK YOU FOR READING THIS FAR. That is a rough summary of me writing bash for a month there is really a lot left unsaid here but still building and learning. If you are just starting out with bash or if you haven't tried it hope this helps&lt;/em&gt;&lt;br&gt;
&lt;strong&gt;&lt;em&gt;feel free to drop questions advice and corrections&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;




</description>
      <category>bash</category>
      <category>linux</category>
      <category>automation</category>
    </item>
    <item>
      <title>A Month With Bash — Part 2: Expansions</title>
      <dc:creator>Kengah Ireneaus</dc:creator>
      <pubDate>Tue, 04 Aug 2026 00:26:00 +0000</pubDate>
      <link>https://dev.to/4kit1-glitch/a-month-with-bash-part-2-expansions-3277</link>
      <guid>https://dev.to/4kit1-glitch/a-month-with-bash-part-2-expansions-3277</guid>
      <description>&lt;h2&gt;
  
  
  A Month With Bash — Part 2: Expansions
&lt;/h2&gt;

&lt;p&gt;Continuing from where I left off, the next thing I learned was special parameters in bash:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;"$*"&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;$#&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;$?&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;$@&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;$N&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;$-&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;$0&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Another important concept I picked up is how bash executes shell scripts. Bash is one of those languages that interprets each line as it goes — but it doesn't stop if a line fails. It continues on unless you explicitly set &lt;code&gt;set -o pipefail&lt;/code&gt; (or &lt;code&gt;-e&lt;/code&gt;, depending on what you want it to catch).&lt;/p&gt;

&lt;p&gt;Generally, the procedure looks like this:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Tokenizing&lt;/strong&gt;: splitting the line into tokens, usually split using the &lt;code&gt;IFS&lt;/code&gt; value.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Brace expansion&lt;/strong&gt;: a mechanism by which arbitrary strings can be generated.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;echo &lt;/span&gt;file&lt;span class="o"&gt;{&lt;/span&gt;1,2,3&lt;span class="o"&gt;}&lt;/span&gt;.txt
&lt;span class="c"&gt;## output: file1.txt file2.txt file3.txt&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Bash preserves the order from left to right.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Tilde expansion&lt;/strong&gt;: this is where expansion of special symbols takes place.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;~&lt;/code&gt; represents the &lt;code&gt;HOME&lt;/code&gt; built-in variable&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;~+&lt;/code&gt; represents &lt;code&gt;PWD&lt;/code&gt;, the current working directory&lt;/li&gt;
&lt;li&gt;and others
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;DIR&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;~/Desktop &lt;span class="c"&gt;# this is $HOME/Desktop&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$DIR&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Parameter expansion&lt;/strong&gt;: introduced with the &lt;code&gt;$&lt;/code&gt; symbol.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# ${} — the braces can be omitted for normal variables but not for array-type variables&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Command substitution&lt;/strong&gt;: very important — it lets you assign the output of a command to a variable, and use commands inside &lt;code&gt;if&lt;/code&gt; and &lt;code&gt;for&lt;/code&gt; statements. Done with &lt;code&gt;$(command to execute)&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;week_name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;date&lt;/span&gt; +%A&lt;span class="si"&gt;)&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="c"&gt;# gets the current day of the week&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$week_name&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Generally, &lt;code&gt;$()&lt;/code&gt; spawns a new shell instance, so it's advisable to avoid it where possible, for latency reasons.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Arithmetic expansion&lt;/strong&gt;: just from the name, this allows evaluation of arithmetic expressions and substitution of the result. It starts with &lt;code&gt;$(( expression ))&lt;/code&gt;. There are some rules — bash doesn't support floating point arithmetic natively, so you'd reach for &lt;code&gt;bc&lt;/code&gt; if you need it. I won't go deep into that here since this isn't a full bash tutorial.&lt;/p&gt;

&lt;p&gt;Here's a simple BMI calculator I wrote while practicing this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;#!/usr/bin/env bash&lt;/span&gt;

&lt;span class="c"&gt;# script calculates user's BMI and gives a recommendation&lt;/span&gt;

&lt;span class="nb"&gt;set&lt;/span&gt; &lt;span class="nt"&gt;-euo&lt;/span&gt; pipefail

&lt;span class="c"&gt;# ---------------- read parameters ----------------&lt;/span&gt;
&lt;span class="nv"&gt;weight&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$1&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;span class="nv"&gt;height&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$2&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;

&lt;span class="nv"&gt;bmi&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;bc &lt;span class="nt"&gt;-q&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="s2"&gt;"scale=2; &lt;/span&gt;&lt;span class="nv"&gt;$weight&lt;/span&gt;&lt;span class="s2"&gt; / (&lt;/span&gt;&lt;span class="nv"&gt;$height&lt;/span&gt;&lt;span class="s2"&gt;^2)"&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;

&lt;span class="c"&gt;# ---------------- test ----------------&lt;/span&gt;
&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;((&lt;/span&gt; &lt;span class="si"&gt;$(&lt;/span&gt;bc &lt;span class="nt"&gt;-q&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$bmi&lt;/span&gt;&lt;span class="s2"&gt; &amp;lt; 18.5"&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt; &lt;span class="o"&gt;))&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;then
    &lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"UNDERWEIGHT"&lt;/span&gt;
&lt;span class="k"&gt;elif&lt;/span&gt; &lt;span class="o"&gt;((&lt;/span&gt; &lt;span class="si"&gt;$(&lt;/span&gt;bc &lt;span class="nt"&gt;-q&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$bmi&lt;/span&gt;&lt;span class="s2"&gt; &amp;lt; 25"&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt; &lt;span class="o"&gt;))&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;then
    &lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"normal weight"&lt;/span&gt;
&lt;span class="k"&gt;elif&lt;/span&gt; &lt;span class="o"&gt;((&lt;/span&gt; &lt;span class="si"&gt;$(&lt;/span&gt;bc &lt;span class="nt"&gt;-q&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$bmi&lt;/span&gt;&lt;span class="s2"&gt; &amp;lt; 30"&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt; &lt;span class="o"&gt;))&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;then
    &lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"overweight"&lt;/span&gt;
&lt;span class="k"&gt;else
    &lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"obese"&lt;/span&gt;
&lt;span class="k"&gt;fi&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Process substitution&lt;/strong&gt;: this saves the output of a process into a temporary file-like descriptor under &lt;code&gt;/dev/fd/N&lt;/code&gt;. It lets you feed command output into programs that expect a file as input. Done with &lt;code&gt;&amp;gt;(command)&lt;/code&gt; and &lt;code&gt;&amp;lt;(command)&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;#!/usr/bin/env bash&lt;/span&gt;

&lt;span class="c"&gt;# script demonstrates process substitution&lt;/span&gt;
&lt;span class="c"&gt;# process substitution is when you want to use the output of a command&lt;/span&gt;
&lt;span class="c"&gt;# as the input to a command that needs files as parameters&lt;/span&gt;

&lt;span class="nb"&gt;set&lt;/span&gt; &lt;span class="nt"&gt;-euo&lt;/span&gt; pipefail

&lt;span class="c"&gt;# gets the difference between two texts without making temp files&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;diff &lt;span class="nt"&gt;-p&lt;/span&gt; &amp;lt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"hello mr beast"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &amp;lt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"hello mr beast."&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;

&lt;span class="c"&gt;# note: &amp;lt;(cmd) uses the output of a command as a file&lt;/span&gt;
&lt;span class="c"&gt;# &amp;gt;(cmd) takes input from a program and feeds it to the command as a file&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Word splitting and globbing&lt;/strong&gt;: occurs after expansion, only on unquoted values.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Next up: regex, grep/sed/awk, and moving into building actual projects.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>bash</category>
      <category>linux</category>
      <category>automation</category>
      <category>fedora</category>
    </item>
    <item>
      <title>A month with bash</title>
      <dc:creator>Kengah Ireneaus</dc:creator>
      <pubDate>Mon, 03 Aug 2026 14:20:00 +0000</pubDate>
      <link>https://dev.to/4kit1-glitch/a-month-with-bash-490g</link>
      <guid>https://dev.to/4kit1-glitch/a-month-with-bash-490g</guid>
      <description>&lt;h2&gt;
  
  
  A Month With Bash
&lt;/h2&gt;

&lt;p&gt;*this began as one long write-up but i decided to split it into three parts &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://dev.tolink"&gt;Part 1: Getting Started&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/4kit1-glitch/a-month-with-bash-part-2-expansions-3277"&gt;Part 2: Going deeper&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/4kit1-glitch/a-month-with-bash-part-3-building-projects-3od9"&gt;Part 3: Project building&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A month ago I decided to learn bash so I could use my Fedora machine more effectively. My original plan was to just learn some commands and get over with it, but as I began reading resources and books, I quickly noticed how important it is for Linux users, automation experts, and system admins. The thing that amazed me most is that I could literally automate almost every repetitive process I do on my PC.&lt;/p&gt;

&lt;h2&gt;
  
  
  Getting Started
&lt;/h2&gt;

&lt;p&gt;Starting off with bash wasn't really bad or difficult, maybe because I already had experience programming in C and Python. Learning the basic syntax of bash wasn't much of a problem — things like variables and printing to the terminal were quite easy to grasp. I also learned some theory on shell types and their differences, which wasn't too hard either.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# create, assign, and print a variable&lt;/span&gt;
&lt;span class="nv"&gt;my_var&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"declared"&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$my_var&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Moving Deeper Into Bash
&lt;/h2&gt;

&lt;p&gt;After the basics, where bash just seemed like a small programming language, things changed once I started learning about the bash environment. This is what began to show me what makes it special and unique. I learned about:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Shell initialization scripts

&lt;ul&gt;
&lt;li&gt;System-wide&lt;/li&gt;
&lt;li&gt;Individual user scripts&lt;/li&gt;
&lt;li&gt;How to configure them&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Honestly, these files affect system behavior, so it's better to avoid touching them unless you know what you're doing. This part was quite confusing at first, but with practice it became clearer. I still don't fully understand every use case of these initialization scripts off-hand, and explaining them isn't the goal of this post.&lt;/p&gt;

&lt;p&gt;After that I took some time to learn about reserved variables — just a curated table of them. They're very useful because they enable some handy functionality, and they're good to use when making a script portable. Some important ones:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;HOME&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;IFS&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;PWD&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;PATH&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;DIRSTACK&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;location&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$HOME&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="c"&gt;# this stores the location of the home directory&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$location&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;Next up: special parameters, expansions, and how bash actually executes a script line by line.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>bash</category>
      <category>linux</category>
      <category>automation</category>
    </item>
  </channel>
</rss>
