<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>awk · wleeaf field notes</title><link>https://articles.wleeaf.dev/tags/awk/</link><description>Hands-on guides and build logs from the wleeaf studio: self-hosting, Linux, networking, Docker, the command line and reverse engineering.</description><language>en-us</language><lastBuildDate>Sat, 04 Apr 2026 00:00:00 +0000</lastBuildDate><atom:link href="https://articles.wleeaf.dev/tags/awk/feed.xml" rel="self" type="application/rss+xml"/><item><title>awk in 10 Minutes With Practical Examples</title><link>https://articles.wleeaf.dev/posts/awk-practical-examples/</link><pubDate>Sat, 04 Apr 2026 00:00:00 +0000</pubDate><guid>https://articles.wleeaf.dev/posts/awk-practical-examples/</guid><description>Nobody reads the awk manual. Here are the patterns that cover 90% of real-world use.</description><category>awk</category><category>cli</category><category>linux</category><content:encoded><![CDATA[<p>awk is one of those tools that looks intimidating until you learn five patterns. Then you use it every day. I am not going to explain the full language. Here are the patterns that actually matter.</p>
<h2 id="pattern-1-print-a-column">Pattern 1: Print a Column<a class="anchor" href="#pattern-1-print-a-column" aria-label="Link to “Pattern 1: Print a Column”">#</a></h2>
<p>awk splits each line into fields. <code>$1</code> is the first, <code>$2</code> is the second, <code>$0</code> is the whole line:</p>
<div class="code">
<div class="code-head"><span class="code-lang">bash</span><button type="button" class="code-copy" data-copy-code hidden><svg viewBox="0 0 24 24" aria-hidden="true"><rect x="8" y="8" width="12" height="12" rx="2.5"/><path d="M16 8V6.5A2.5 2.5 0 0 0 13.5 4h-7A2.5 2.5 0 0 0 4 6.5v7A2.5 2.5 0 0 0 6.5 16H8"/></svg><span>Copy</span></button></div>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl"><span class="c1"># Print the first column of ps output</span>
</span></span><span class="line"><span class="cl">ps aux <span class="p">|</span> awk <span class="s1">&#39;{print $1}&#39;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Print columns 1 and 11 (user and command)</span>
</span></span><span class="line"><span class="cl">ps aux <span class="p">|</span> awk <span class="s1">&#39;{print $1, $11}&#39;</span></span></span></code></pre></div>
</div>
<p>The default field separator is whitespace. Change it with <code>-F</code>:</p>
<div class="code">
<div class="code-head"><span class="code-lang">bash</span><button type="button" class="code-copy" data-copy-code hidden><svg viewBox="0 0 24 24" aria-hidden="true"><rect x="8" y="8" width="12" height="12" rx="2.5"/><path d="M16 8V6.5A2.5 2.5 0 0 0 13.5 4h-7A2.5 2.5 0 0 0 4 6.5v7A2.5 2.5 0 0 0 6.5 16H8"/></svg><span>Copy</span></button></div>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl"><span class="c1"># Parse /etc/passwd (colon-separated)</span>
</span></span><span class="line"><span class="cl">awk -F: <span class="s1">&#39;{print $1, $7}&#39;</span> /etc/passwd
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Parse CSV</span>
</span></span><span class="line"><span class="cl">awk -F, <span class="s1">&#39;{print $2}&#39;</span> data.csv</span></span></code></pre></div>
</div>
<h2 id="pattern-2-filter-rows">Pattern 2: Filter Rows<a class="anchor" href="#pattern-2-filter-rows" aria-label="Link to “Pattern 2: Filter Rows”">#</a></h2>
<p>Put a condition before the action:</p>
<div class="code">
<div class="code-head"><span class="code-lang">bash</span><button type="button" class="code-copy" data-copy-code hidden><svg viewBox="0 0 24 24" aria-hidden="true"><rect x="8" y="8" width="12" height="12" rx="2.5"/><path d="M16 8V6.5A2.5 2.5 0 0 0 13.5 4h-7A2.5 2.5 0 0 0 4 6.5v7A2.5 2.5 0 0 0 6.5 16H8"/></svg><span>Copy</span></button></div>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl"><span class="c1"># Lines where column 3 is greater than 100</span>
</span></span><span class="line"><span class="cl">awk <span class="s1">&#39;$3 &gt; 100&#39;</span> data.txt
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Lines containing &#34;ERROR&#34;</span>
</span></span><span class="line"><span class="cl">awk <span class="s1">&#39;/ERROR/&#39;</span> app.log
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Lines where the first field matches a pattern</span>
</span></span><span class="line"><span class="cl">awk <span class="s1">&#39;$1 ~ /^192\.168/&#39;</span> access.log</span></span></code></pre></div>
</div>
<p>Combine conditions:</p>
<div class="code">
<div class="code-head"><span class="code-lang">bash</span><button type="button" class="code-copy" data-copy-code hidden><svg viewBox="0 0 24 24" aria-hidden="true"><rect x="8" y="8" width="12" height="12" rx="2.5"/><path d="M16 8V6.5A2.5 2.5 0 0 0 13.5 4h-7A2.5 2.5 0 0 0 4 6.5v7A2.5 2.5 0 0 0 6.5 16H8"/></svg><span>Copy</span></button></div>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl"><span class="c1"># Memory usage over 50% AND the process is not root</span>
</span></span><span class="line"><span class="cl">ps aux <span class="p">|</span> awk <span class="s1">&#39;$4 &gt; 50.0 &amp;&amp; $1 != &#34;root&#34; {print $1, $4, $11}&#39;</span></span></span></code></pre></div>
</div>
<h2 id="pattern-3-sum-a-column">Pattern 3: Sum a Column<a class="anchor" href="#pattern-3-sum-a-column" aria-label="Link to “Pattern 3: Sum a Column”">#</a></h2>
<div class="code">
<div class="code-head"><span class="code-lang">bash</span><button type="button" class="code-copy" data-copy-code hidden><svg viewBox="0 0 24 24" aria-hidden="true"><rect x="8" y="8" width="12" height="12" rx="2.5"/><path d="M16 8V6.5A2.5 2.5 0 0 0 13.5 4h-7A2.5 2.5 0 0 0 4 6.5v7A2.5 2.5 0 0 0 6.5 16H8"/></svg><span>Copy</span></button></div>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl"><span class="c1"># Total bytes transferred (column 10 in access logs)</span>
</span></span><span class="line"><span class="cl">awk <span class="s1">&#39;{sum += $10} END {print sum}&#39;</span> access.log
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Average response time</span>
</span></span><span class="line"><span class="cl">awk <span class="s1">&#39;{sum += $NF; n++} END {print sum/n}&#39;</span> response_times.log</span></span></code></pre></div>
</div>
<p><code>END</code> runs after all lines are processed. <code>NF</code> is the number of fields on the current line, so <code>$NF</code> is the last field.</p>
<h2 id="pattern-4-count-and-group">Pattern 4: Count and Group<a class="anchor" href="#pattern-4-count-and-group" aria-label="Link to “Pattern 4: Count and Group”">#</a></h2>
<div class="code">
<div class="code-head"><span class="code-lang">bash</span><button type="button" class="code-copy" data-copy-code hidden><svg viewBox="0 0 24 24" aria-hidden="true"><rect x="8" y="8" width="12" height="12" rx="2.5"/><path d="M16 8V6.5A2.5 2.5 0 0 0 13.5 4h-7A2.5 2.5 0 0 0 4 6.5v7A2.5 2.5 0 0 0 6.5 16H8"/></svg><span>Copy</span></button></div>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl"><span class="c1"># Count HTTP status codes</span>
</span></span><span class="line"><span class="cl">awk <span class="s1">&#39;{count[$9]++} END {for (c in count) print c, count[c]}&#39;</span> access.log <span class="p">|</span> sort -rn -k2
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Output:</span>
</span></span><span class="line"><span class="cl"><span class="c1"># 200 45231</span>
</span></span><span class="line"><span class="cl"><span class="c1"># 304 12044</span>
</span></span><span class="line"><span class="cl"><span class="c1"># 404 891</span>
</span></span><span class="line"><span class="cl"><span class="c1"># 500 23</span></span></span></code></pre></div>
</div>
<p>This uses an associative array. <code>count[$9]++</code> increments the count for each unique value in column 9.</p>
<p>Top 10 IP addresses by request count:</p>
<div class="code">
<div class="code-head"><span class="code-lang">bash</span><button type="button" class="code-copy" data-copy-code hidden><svg viewBox="0 0 24 24" aria-hidden="true"><rect x="8" y="8" width="12" height="12" rx="2.5"/><path d="M16 8V6.5A2.5 2.5 0 0 0 13.5 4h-7A2.5 2.5 0 0 0 4 6.5v7A2.5 2.5 0 0 0 6.5 16H8"/></svg><span>Copy</span></button></div>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">awk <span class="s1">&#39;{count[$1]++} END {for (ip in count) print count[ip], ip}&#39;</span> access.log <span class="p">|</span> sort -rn <span class="p">|</span> head -10</span></span></code></pre></div>
</div>
<h2 id="pattern-5-transform-fields">Pattern 5: Transform Fields<a class="anchor" href="#pattern-5-transform-fields" aria-label="Link to “Pattern 5: Transform Fields”">#</a></h2>
<div class="code">
<div class="code-head"><span class="code-lang">bash</span><button type="button" class="code-copy" data-copy-code hidden><svg viewBox="0 0 24 24" aria-hidden="true"><rect x="8" y="8" width="12" height="12" rx="2.5"/><path d="M16 8V6.5A2.5 2.5 0 0 0 13.5 4h-7A2.5 2.5 0 0 0 4 6.5v7A2.5 2.5 0 0 0 6.5 16H8"/></svg><span>Copy</span></button></div>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl"><span class="c1"># Convert bytes to megabytes</span>
</span></span><span class="line"><span class="cl">awk <span class="s1">&#39;{printf &#34;%s %.1fMB\n&#34;, $1, $2/1048576}&#39;</span> sizes.txt
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Add a prefix to every line</span>
</span></span><span class="line"><span class="cl">awk <span class="s1">&#39;{print &#34;[INFO]&#34;, $0}&#39;</span> app.log
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Swap two columns</span>
</span></span><span class="line"><span class="cl">awk <span class="s1">&#39;{temp=$1; $1=$2; $2=temp; print}&#39;</span> data.txt</span></span></code></pre></div>
</div>
<h2 id="real-world-examples">Real-World Examples<a class="anchor" href="#real-world-examples" aria-label="Link to “Real-World Examples”">#</a></h2>
<h3 id="parse-docker-ps-output">Parse Docker ps output<a class="anchor" href="#parse-docker-ps-output" aria-label="Link to “Parse Docker ps output”">#</a></h3>
<div class="code">
<div class="code-head"><span class="code-lang">bash</span><button type="button" class="code-copy" data-copy-code hidden><svg viewBox="0 0 24 24" aria-hidden="true"><rect x="8" y="8" width="12" height="12" rx="2.5"/><path d="M16 8V6.5A2.5 2.5 0 0 0 13.5 4h-7A2.5 2.5 0 0 0 4 6.5v7A2.5 2.5 0 0 0 6.5 16H8"/></svg><span>Copy</span></button></div>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">docker ps --format <span class="s1">&#39;{{.Names}}\t{{.Status}}\t{{.Ports}}&#39;</span> <span class="p">|</span> <span class="se">\
</span></span></span><span class="line"><span class="cl"><span class="se"></span>  awk -F<span class="s1">&#39;\t&#39;</span> <span class="s1">&#39;{printf &#34;%-20s %-15s %s\n&#34;, $1, $2, $3}&#39;</span></span></span></code></pre></div>
</div>
<h3 id="find-the-largest-docker-images">Find the largest Docker images<a class="anchor" href="#find-the-largest-docker-images" aria-label="Link to “Find the largest Docker images”">#</a></h3>
<div class="code">
<div class="code-head"><span class="code-lang">bash</span><button type="button" class="code-copy" data-copy-code hidden><svg viewBox="0 0 24 24" aria-hidden="true"><rect x="8" y="8" width="12" height="12" rx="2.5"/><path d="M16 8V6.5A2.5 2.5 0 0 0 13.5 4h-7A2.5 2.5 0 0 0 4 6.5v7A2.5 2.5 0 0 0 6.5 16H8"/></svg><span>Copy</span></button></div>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">docker images --format <span class="s1">&#39;{{.Repository}}:{{.Tag}}\t{{.Size}}&#39;</span> <span class="p">|</span> <span class="se">\
</span></span></span><span class="line"><span class="cl"><span class="se"></span>  awk -F<span class="s1">&#39;\t&#39;</span> <span class="s1">&#39;{
</span></span></span><span class="line"><span class="cl"><span class="s1">    size = $2
</span></span></span><span class="line"><span class="cl"><span class="s1">    if (size ~ /GB/) {
</span></span></span><span class="line"><span class="cl"><span class="s1">      gsub(/GB/, &#34;&#34;, size)
</span></span></span><span class="line"><span class="cl"><span class="s1">      mb = size * 1024
</span></span></span><span class="line"><span class="cl"><span class="s1">    } else if (size ~ /MB/) {
</span></span></span><span class="line"><span class="cl"><span class="s1">      gsub(/MB/, &#34;&#34;, size)
</span></span></span><span class="line"><span class="cl"><span class="s1">      mb = size
</span></span></span><span class="line"><span class="cl"><span class="s1">    } else {
</span></span></span><span class="line"><span class="cl"><span class="s1">      mb = 0
</span></span></span><span class="line"><span class="cl"><span class="s1">    }
</span></span></span><span class="line"><span class="cl"><span class="s1">    printf &#34;%8.0fMB  %s\n&#34;, mb, $1
</span></span></span><span class="line"><span class="cl"><span class="s1">  }&#39;</span> <span class="p">|</span> sort -rn <span class="p">|</span> head -10</span></span></code></pre></div>
</div>
<h3 id="calculate-uptime-percentage">Calculate uptime percentage<a class="anchor" href="#calculate-uptime-percentage" aria-label="Link to “Calculate uptime percentage”">#</a></h3>
<p>Given a log with timestamps and status:</p>
<div class="code">
<div class="code-head"><span class="code-lang">bash</span><button type="button" class="code-copy" data-copy-code hidden><svg viewBox="0 0 24 24" aria-hidden="true"><rect x="8" y="8" width="12" height="12" rx="2.5"/><path d="M16 8V6.5A2.5 2.5 0 0 0 13.5 4h-7A2.5 2.5 0 0 0 4 6.5v7A2.5 2.5 0 0 0 6.5 16H8"/></svg><span>Copy</span></button></div>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">awk <span class="s1">&#39;
</span></span></span><span class="line"><span class="cl"><span class="s1">  /UP/   { up++ }
</span></span></span><span class="line"><span class="cl"><span class="s1">  /DOWN/ { down++ }
</span></span></span><span class="line"><span class="cl"><span class="s1">  END {
</span></span></span><span class="line"><span class="cl"><span class="s1">    total = up + down
</span></span></span><span class="line"><span class="cl"><span class="s1">    if (total &gt; 0)
</span></span></span><span class="line"><span class="cl"><span class="s1">      printf &#34;Uptime: %.2f%% (%d/%d checks)\n&#34;, (up/total)*100, up, total
</span></span></span><span class="line"><span class="cl"><span class="s1">  }
</span></span></span><span class="line"><span class="cl"><span class="s1">&#39;</span> monitoring.log</span></span></code></pre></div>
</div>
<h3 id="extract-unique-error-messages">Extract unique error messages<a class="anchor" href="#extract-unique-error-messages" aria-label="Link to “Extract unique error messages”">#</a></h3>
<div class="code">
<div class="code-head"><span class="code-lang">bash</span><button type="button" class="code-copy" data-copy-code hidden><svg viewBox="0 0 24 24" aria-hidden="true"><rect x="8" y="8" width="12" height="12" rx="2.5"/><path d="M16 8V6.5A2.5 2.5 0 0 0 13.5 4h-7A2.5 2.5 0 0 0 4 6.5v7A2.5 2.5 0 0 0 6.5 16H8"/></svg><span>Copy</span></button></div>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">awk <span class="s1">&#39;/ERROR/ {
</span></span></span><span class="line"><span class="cl"><span class="s1">  msg = &#34;&#34;
</span></span></span><span class="line"><span class="cl"><span class="s1">  for (i=4; i&lt;=NF; i++) msg = msg &#34; &#34; $i
</span></span></span><span class="line"><span class="cl"><span class="s1">  errors[msg]++
</span></span></span><span class="line"><span class="cl"><span class="s1">}
</span></span></span><span class="line"><span class="cl"><span class="s1">END {
</span></span></span><span class="line"><span class="cl"><span class="s1">  for (e in errors) printf &#34;%5d %s\n&#34;, errors[e], e
</span></span></span><span class="line"><span class="cl"><span class="s1">}&#39;</span> app.log <span class="p">|</span> sort -rn <span class="p">|</span> head -20</span></span></code></pre></div>
</div>
<h2 id="built-in-variables">Built-in Variables<a class="anchor" href="#built-in-variables" aria-label="Link to “Built-in Variables”">#</a></h2>
<table>
  <thead>
      <tr>
          <th>Variable</th>
          <th>Meaning</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td><code>NR</code></td>
          <td>Current line number</td>
      </tr>
      <tr>
          <td><code>NF</code></td>
          <td>Number of fields on current line</td>
      </tr>
      <tr>
          <td><code>FS</code></td>
          <td>Field separator</td>
      </tr>
      <tr>
          <td><code>OFS</code></td>
          <td>Output field separator</td>
      </tr>
      <tr>
          <td><code>$0</code></td>
          <td>Entire line</td>
      </tr>
      <tr>
          <td><code>$1..$n</code></td>
          <td>Individual fields</td>
      </tr>
      <tr>
          <td><code>FILENAME</code></td>
          <td>Current filename</td>
      </tr>
  </tbody>
</table>
<h2 id="when-to-use-awk-vs-other-tools">When to Use awk vs. Other Tools<a class="anchor" href="#when-to-use-awk-vs-other-tools" aria-label="Link to “When to Use awk vs. Other Tools”">#</a></h2>
<ul>
<li><strong>cut</strong>: When you just need a column and nothing else. <code>cut -d: -f1 /etc/passwd</code> is simpler than awk for trivial extraction.</li>
<li><strong>grep</strong>: When you just need to filter lines by a pattern.</li>
<li><strong>sed</strong>: When you need to do find-and-replace on text.</li>
<li><strong>awk</strong>: When you need to do math, grouping, conditional logic, or work with multiple fields at once.</li>
</ul>
<p>The mental model is simple. awk reads lines, splits them into fields, and lets you write rules about what to do with each line. Once that clicks, you start seeing awk solutions everywhere.</p>
]]></content:encoded></item></channel></rss>