DIY Line Counter: Build a Simple Script to Count Lines Quickly
Counting lines in files is a common need for developers, writers, and data workers. A lightweight, custom line-counter script can be faster and more flexible than installing third-party tools. Below is a simple, cross-platform guide to build fast line counters in three popular scripting languages: Bash, Python, and PowerShell. Each version handles multiple files, counts total lines, and skips blank lines optionally.
Features
- Count lines per file and overall total
- Optional skip-blank-lines mode
- Handles large files efficiently
- Cross-platform options (Bash for Unix-like, PowerShell for Windows, Python for all)
1) Bash (Unix-like systems)
Save as count_lines.sh and make executable (chmod +x countlines.sh).
bash
#!/usr/bin/env bash # Simple line counter. Usage: ./count_lines.sh [-s] file1 [file2 …] skip_blank=false if [[ “\(1</span><span class="token" style="color: rgb(163, 21, 21);">"</span><span> </span><span class="token" style="color: rgb(57, 58, 52);">==</span><span> </span><span class="token" style="color: rgb(163, 21, 21);">"-s"</span><span> </span><span class="token" style="color: rgb(57, 58, 52);">]</span><span class="token" style="color: rgb(57, 58, 52);">]</span><span class="token" style="color: rgb(57, 58, 52);">;</span><span> </span><span class="token" style="color: rgb(0, 0, 255);">then</span><span> </span><span></span><span class="token assign-left" style="color: rgb(54, 172, 170);">skip_blank</span><span class="token" style="color: rgb(57, 58, 52);">=</span><span>true </span><span> </span><span class="token builtin" style="color: rgb(43, 145, 175);">shift</span><span> </span><span></span><span class="token" style="color: rgb(0, 0, 255);">fi</span><span> </span> <span></span><span class="token assign-left" style="color: rgb(54, 172, 170);">total</span><span class="token" style="color: rgb(57, 58, 52);">=</span><span class="token" style="color: rgb(54, 172, 170);">0</span><span> </span><span></span><span class="token" style="color: rgb(0, 0, 255);">for</span><span> </span><span class="token for-or-select" style="color: rgb(54, 172, 170);">f</span><span> </span><span class="token" style="color: rgb(0, 0, 255);">in</span><span> </span><span class="token" style="color: rgb(163, 21, 21);">"</span><span class="token" style="color: rgb(54, 172, 170);">\)@”; do if [[ ! -f “\(f</span><span class="token" style="color: rgb(163, 21, 21);">"</span><span> </span><span class="token" style="color: rgb(57, 58, 52);">]</span><span class="token" style="color: rgb(57, 58, 52);">]</span><span class="token" style="color: rgb(57, 58, 52);">;</span><span> </span><span class="token" style="color: rgb(0, 0, 255);">then</span><span> </span><span> </span><span class="token builtin" style="color: rgb(43, 145, 175);">echo</span><span> </span><span class="token" style="color: rgb(163, 21, 21);">"Skipped: </span><span class="token" style="color: rgb(54, 172, 170);">\)f (not a file)” continue fi if \(skip_blank</span><span class="token" style="color: rgb(57, 58, 52);">;</span><span> </span><span class="token" style="color: rgb(0, 0, 255);">then</span><span> </span><span> </span><span class="token assign-left" style="color: rgb(54, 172, 170);">lines</span><span class="token" style="color: rgb(57, 58, 52);">=</span><span class="token" style="color: rgb(54, 172, 170);">\)(grep -cve ’^[[:space:]]*\('</span><span class="token" style="color: rgb(54, 172, 170);"> </span><span class="token" style="color: rgb(163, 21, 21);">"</span><span class="token" style="color: rgb(163, 21, 21);">\)f“) else lines=\((</span><span class="token" style="color: rgb(57, 58, 52);">wc</span><span class="token" style="color: rgb(54, 172, 170);"> -l </span><span class="token" style="color: rgb(57, 58, 52);"><</span><span class="token" style="color: rgb(54, 172, 170);"> </span><span class="token" style="color: rgb(163, 21, 21);">"</span><span class="token" style="color: rgb(163, 21, 21);">\)f”) lines=\({lines</span><span class="token" style="color: rgb(57, 58, 52);">/</span><span class="token" style="color: rgb(57, 58, 52);">/</span><span class="token" style="color: rgb(54, 172, 170);"> </span><span class="token" style="color: rgb(57, 58, 52);">/</span><span class="token" style="color: rgb(54, 172, 170);">}</span><span> </span><span> </span><span class="token" style="color: rgb(0, 0, 255);">fi</span><span> </span><span> </span><span class="token builtin" style="color: rgb(43, 145, 175);">echo</span><span> </span><span class="token" style="color: rgb(163, 21, 21);">"</span><span class="token" style="color: rgb(54, 172, 170);">\)f: \(lines</span><span class="token" style="color: rgb(163, 21, 21);">"</span><span> </span><span> </span><span class="token assign-left" style="color: rgb(54, 172, 170);">total</span><span class="token" style="color: rgb(57, 58, 52);">=</span><span class="token" style="color: rgb(54, 172, 170);">\)((total + lines)) done echo “Total: \(total</span><span class="token" style="color: rgb(163, 21, 21);">"</span><span> </span></code></div></div></pre> <p>Usage examples:</p> <ul> <li>Count all lines: ./count_lines.sh file1.txt file2.txt</li> <li>Skip blank lines: ./count_lines.sh -s *.md</li> </ul> <p>Notes:</p> <ul> <li>Uses grep for skip-blank which streams efficiently.</li> <li>wc -l works for large files and is very fast.</li> </ul> <hr> <h3>2) Python (cross-platform)</h3> <p>Save as count_lines.py and run with python3 count_lines.py.</p> <pre><div class="XG2rBS5V967VhGTCEN1k"><div class="nHykNMmtaaTJMjgzStID"><div class="HsT0RHFbNELC00WicOi8"><i><svg width="16" height="16" fill="none" xmlns="http://www.w3.org/2000/svg"><path fill="currentColor" fill-rule="evenodd" clip-rule="evenodd" d="M15.434 7.51c.137.137.212.311.212.49a.694.694 0 0 1-.212.5l-3.54 3.5a.893.893 0 0 1-.277.18 1.024 1.024 0 0 1-.684.038.945.945 0 0 1-.302-.148.787.787 0 0 1-.213-.234.652.652 0 0 1-.045-.58.74.74 0 0 1 .175-.256l3.045-3-3.045-3a.69.69 0 0 1-.22-.55.723.723 0 0 1 .303-.52 1 1 0 0 1 .648-.186.962.962 0 0 1 .614.256l3.541 3.51Zm-12.281 0A.695.695 0 0 0 2.94 8a.694.694 0 0 0 .213.5l3.54 3.5a.893.893 0 0 0 .277.18 1.024 1.024 0 0 0 .684.038.945.945 0 0 0 .302-.148.788.788 0 0 0 .213-.234.651.651 0 0 0 .045-.58.74.74 0 0 0-.175-.256L4.994 8l3.045-3a.69.69 0 0 0 .22-.55.723.723 0 0 0-.303-.52 1 1 0 0 0-.648-.186.962.962 0 0 0-.615.256l-3.54 3.51Z"></path></svg></i><p class="li3asHIMe05JPmtJCytG wZ4JdaHxSAhGy1HoNVja cPy9QU4brI7VQXFNPEvF">python</p></div><div class="CF2lgtGWtYUYmTULoX44"><button type="button" class="st68fcLUUT0dNcuLLB2_ ffON2NH02oMAcqyoh2UU MQCbz04ET5EljRmK3YpQ CPXAhl7VTkj2dHDyAYAf" data-copycode="true" role="button" aria-label="Copy Code"><svg viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg"><path fill="currentColor" fill-rule="evenodd" clip-rule="evenodd" d="M9.975 1h.09a3.2 3.2 0 0 1 3.202 3.201v1.924a.754.754 0 0 1-.017.16l1.23 1.353A2 2 0 0 1 15 8.983V14a2 2 0 0 1-2 2H8a2 2 0 0 1-1.733-1H4.183a3.201 3.201 0 0 1-3.2-3.201V4.201a3.2 3.2 0 0 1 3.04-3.197A1.25 1.25 0 0 1 5.25 0h3.5c.604 0 1.109.43 1.225 1ZM4.249 2.5h-.066a1.7 1.7 0 0 0-1.7 1.701v7.598c0 .94.761 1.701 1.7 1.701H6V7a2 2 0 0 1 2-2h3.197c.195 0 .387.028.57.083v-.882A1.7 1.7 0 0 0 10.066 2.5H9.75c-.228.304-.591.5-1 .5h-3.5c-.41 0-.772-.196-1-.5ZM5 1.75v-.5A.25.25 0 0 1 5.25 1h3.5a.25.25 0 0 1 .25.25v.5a.25.25 0 0 1-.25.25h-3.5A.25.25 0 0 1 5 1.75ZM7.5 7a.5.5 0 0 1 .5-.5h3V9a1 1 0 0 0 1 1h1.5v4a.5.5 0 0 1-.5.5H8a.5.5 0 0 1-.5-.5V7Zm6 2v-.017a.5.5 0 0 0-.13-.336L12 7.14V9h1.5Z"></path></svg>Copy Code</button><button type="button" class="st68fcLUUT0dNcuLLB2_ WtfzoAXPoZC2mMqcexgL ffON2NH02oMAcqyoh2UU MQCbz04ET5EljRmK3YpQ GnLX_jUB3Jn3idluie7R"><svg fill="none" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path fill="currentColor" fill-rule="evenodd" d="M20.618 4.214a1 1 0 0 1 .168 1.404l-11 14a1 1 0 0 1-1.554.022l-5-6a1 1 0 0 1 1.536-1.28l4.21 5.05L19.213 4.382a1 1 0 0 1 1.404-.168Z" clip-rule="evenodd"></path></svg>Copied</button></div></div><div class="mtDfw7oSa1WexjXyzs9y" style="color: var(--sds-color-text-01); font-family: var(--sds-font-family-monospace); direction: ltr; text-align: left; white-space: pre; word-spacing: normal; word-break: normal; font-size: var(--sds-font-size-label); line-height: 1.2em; tab-size: 4; hyphens: none; padding: var(--sds-space-x02, 8px) var(--sds-space-x04, 16px) var(--sds-space-x04, 16px); margin: 0px; overflow: auto; border: none; background: transparent;"><code class="language-python" style="color: rgb(57, 58, 52); font-family: Consolas, "Bitstream Vera Sans Mono", "Courier New", Courier, monospace; direction: ltr; text-align: left; white-space: pre; word-spacing: normal; word-break: normal; font-size: 0.9em; line-height: 1.2em; tab-size: 4; hyphens: none;"><span class="token" style="color: rgb(0, 128, 0); font-style: italic;">#!/usr/bin/env python3</span><span> </span><span></span><span class="token" style="color: rgb(0, 128, 0); font-style: italic;"># Usage: python3 count_lines.py [-s] file1 file2 ...</span><span> </span><span></span><span class="token" style="color: rgb(0, 0, 255);">import</span><span> sys </span> <span>skip_blank </span><span class="token" style="color: rgb(57, 58, 52);">=</span><span> </span><span class="token" style="color: rgb(54, 172, 170);">False</span><span> </span><span>args </span><span class="token" style="color: rgb(57, 58, 52);">=</span><span> sys</span><span class="token" style="color: rgb(57, 58, 52);">.</span><span>argv</span><span class="token" style="color: rgb(57, 58, 52);">[</span><span class="token" style="color: rgb(54, 172, 170);">1</span><span class="token" style="color: rgb(57, 58, 52);">:</span><span class="token" style="color: rgb(57, 58, 52);">]</span><span> </span><span></span><span class="token" style="color: rgb(0, 0, 255);">if</span><span> args </span><span class="token" style="color: rgb(0, 0, 255);">and</span><span> args</span><span class="token" style="color: rgb(57, 58, 52);">[</span><span class="token" style="color: rgb(54, 172, 170);">0</span><span class="token" style="color: rgb(57, 58, 52);">]</span><span> </span><span class="token" style="color: rgb(57, 58, 52);">==</span><span> </span><span class="token" style="color: rgb(163, 21, 21);">"-s"</span><span class="token" style="color: rgb(57, 58, 52);">:</span><span> </span><span> skip_blank </span><span class="token" style="color: rgb(57, 58, 52);">=</span><span> </span><span class="token" style="color: rgb(54, 172, 170);">True</span><span> </span><span> args </span><span class="token" style="color: rgb(57, 58, 52);">=</span><span> args</span><span class="token" style="color: rgb(57, 58, 52);">[</span><span class="token" style="color: rgb(54, 172, 170);">1</span><span class="token" style="color: rgb(57, 58, 52);">:</span><span class="token" style="color: rgb(57, 58, 52);">]</span><span> </span> <span></span><span class="token" style="color: rgb(0, 0, 255);">if</span><span> </span><span class="token" style="color: rgb(0, 0, 255);">not</span><span> args</span><span class="token" style="color: rgb(57, 58, 52);">:</span><span> </span><span> </span><span class="token" style="color: rgb(0, 0, 255);">print</span><span class="token" style="color: rgb(57, 58, 52);">(</span><span class="token" style="color: rgb(163, 21, 21);">"Usage: count_lines.py [-s] file1 [file2 ...]"</span><span class="token" style="color: rgb(57, 58, 52);">)</span><span> </span><span> sys</span><span class="token" style="color: rgb(57, 58, 52);">.</span><span>exit</span><span class="token" style="color: rgb(57, 58, 52);">(</span><span class="token" style="color: rgb(54, 172, 170);">1</span><span class="token" style="color: rgb(57, 58, 52);">)</span><span> </span> <span>total </span><span class="token" style="color: rgb(57, 58, 52);">=</span><span> </span><span class="token" style="color: rgb(54, 172, 170);">0</span><span> </span><span></span><span class="token" style="color: rgb(0, 0, 255);">for</span><span> path </span><span class="token" style="color: rgb(0, 0, 255);">in</span><span> args</span><span class="token" style="color: rgb(57, 58, 52);">:</span><span> </span><span> </span><span class="token" style="color: rgb(0, 0, 255);">try</span><span class="token" style="color: rgb(57, 58, 52);">:</span><span> </span><span> </span><span class="token" style="color: rgb(0, 0, 255);">with</span><span> </span><span class="token builtin">open</span><span class="token" style="color: rgb(57, 58, 52);">(</span><span>path</span><span class="token" style="color: rgb(57, 58, 52);">,</span><span> </span><span class="token" style="color: rgb(163, 21, 21);">"r"</span><span class="token" style="color: rgb(57, 58, 52);">,</span><span> encoding</span><span class="token" style="color: rgb(57, 58, 52);">=</span><span class="token" style="color: rgb(163, 21, 21);">"utf-8"</span><span class="token" style="color: rgb(57, 58, 52);">,</span><span> errors</span><span class="token" style="color: rgb(57, 58, 52);">=</span><span class="token" style="color: rgb(163, 21, 21);">"ignore"</span><span class="token" style="color: rgb(57, 58, 52);">)</span><span> </span><span class="token" style="color: rgb(0, 0, 255);">as</span><span> f</span><span class="token" style="color: rgb(57, 58, 52);">:</span><span> </span><span> </span><span class="token" style="color: rgb(0, 0, 255);">if</span><span> skip_blank</span><span class="token" style="color: rgb(57, 58, 52);">:</span><span> </span><span> count </span><span class="token" style="color: rgb(57, 58, 52);">=</span><span> </span><span class="token builtin">sum</span><span class="token" style="color: rgb(57, 58, 52);">(</span><span class="token" style="color: rgb(54, 172, 170);">1</span><span> </span><span class="token" style="color: rgb(0, 0, 255);">for</span><span> line </span><span class="token" style="color: rgb(0, 0, 255);">in</span><span> f </span><span class="token" style="color: rgb(0, 0, 255);">if</span><span> line</span><span class="token" style="color: rgb(57, 58, 52);">.</span><span>strip</span><span class="token" style="color: rgb(57, 58, 52);">(</span><span class="token" style="color: rgb(57, 58, 52);">)</span><span class="token" style="color: rgb(57, 58, 52);">)</span><span> </span><span> </span><span class="token" style="color: rgb(0, 0, 255);">else</span><span class="token" style="color: rgb(57, 58, 52);">:</span><span> </span><span> count </span><span class="token" style="color: rgb(57, 58, 52);">=</span><span> </span><span class="token builtin">sum</span><span class="token" style="color: rgb(57, 58, 52);">(</span><span class="token" style="color: rgb(54, 172, 170);">1</span><span> </span><span class="token" style="color: rgb(0, 0, 255);">for</span><span> _ </span><span class="token" style="color: rgb(0, 0, 255);">in</span><span> f</span><span class="token" style="color: rgb(57, 58, 52);">)</span><span> </span><span> </span><span class="token" style="color: rgb(0, 0, 255);">print</span><span class="token" style="color: rgb(57, 58, 52);">(</span><span class="token string-interpolation" style="color: rgb(163, 21, 21);">f"</span><span class="token string-interpolation interpolation" style="color: rgb(57, 58, 52);">{</span><span class="token string-interpolation interpolation">path</span><span class="token string-interpolation interpolation" style="color: rgb(57, 58, 52);">}</span><span class="token string-interpolation" style="color: rgb(163, 21, 21);">: </span><span class="token string-interpolation interpolation" style="color: rgb(57, 58, 52);">{</span><span class="token string-interpolation interpolation">count</span><span class="token string-interpolation interpolation" style="color: rgb(57, 58, 52);">}</span><span class="token string-interpolation" style="color: rgb(163, 21, 21);">"</span><span class="token" style="color: rgb(57, 58, 52);">)</span><span> </span><span> total </span><span class="token" style="color: rgb(57, 58, 52);">+=</span><span> count </span><span> </span><span class="token" style="color: rgb(0, 0, 255);">except</span><span> FileNotFoundError</span><span class="token" style="color: rgb(57, 58, 52);">:</span><span> </span><span> </span><span class="token" style="color: rgb(0, 0, 255);">print</span><span class="token" style="color: rgb(57, 58, 52);">(</span><span class="token string-interpolation" style="color: rgb(163, 21, 21);">f"Skipped: </span><span class="token string-interpolation interpolation" style="color: rgb(57, 58, 52);">{</span><span class="token string-interpolation interpolation">path</span><span class="token string-interpolation interpolation" style="color: rgb(57, 58, 52);">}</span><span class="token string-interpolation" style="color: rgb(163, 21, 21);"> (not found)"</span><span class="token" style="color: rgb(57, 58, 52);">)</span><span> </span><span></span><span class="token" style="color: rgb(0, 0, 255);">print</span><span class="token" style="color: rgb(57, 58, 52);">(</span><span class="token string-interpolation" style="color: rgb(163, 21, 21);">f"Total: </span><span class="token string-interpolation interpolation" style="color: rgb(57, 58, 52);">{</span><span class="token string-interpolation interpolation">total</span><span class="token string-interpolation interpolation" style="color: rgb(57, 58, 52);">}</span><span class="token string-interpolation" style="color: rgb(163, 21, 21);">"</span><span class="token" style="color: rgb(57, 58, 52);">)</span><span> </span></code></div></div></pre> <p>Notes:</p> <ul> <li>Uses generator expressions for memory efficiency.</li> <li>errors="ignore" helps with binary/non-UTF-8 files; adjust if strict decoding is needed.</li> </ul> <hr> <h3>3) PowerShell (Windows)</h3> <p>Save as Count-Lines.ps1 and run in PowerShell: .\Count-Lines.ps1 -SkipBlank -Paths file1,file2</p> <pre><div class="XG2rBS5V967VhGTCEN1k"><div class="nHykNMmtaaTJMjgzStID"><div class="HsT0RHFbNELC00WicOi8"><i><svg width="16" height="16" fill="none" xmlns="http://www.w3.org/2000/svg"><path fill="currentColor" fill-rule="evenodd" clip-rule="evenodd" d="M15.434 7.51c.137.137.212.311.212.49a.694.694 0 0 1-.212.5l-3.54 3.5a.893.893 0 0 1-.277.18 1.024 1.024 0 0 1-.684.038.945.945 0 0 1-.302-.148.787.787 0 0 1-.213-.234.652.652 0 0 1-.045-.58.74.74 0 0 1 .175-.256l3.045-3-3.045-3a.69.69 0 0 1-.22-.55.723.723 0 0 1 .303-.52 1 1 0 0 1 .648-.186.962.962 0 0 1 .614.256l3.541 3.51Zm-12.281 0A.695.695 0 0 0 2.94 8a.694.694 0 0 0 .213.5l3.54 3.5a.893.893 0 0 0 .277.18 1.024 1.024 0 0 0 .684.038.945.945 0 0 0 .302-.148.788.788 0 0 0 .213-.234.651.651 0 0 0 .045-.58.74.74 0 0 0-.175-.256L4.994 8l3.045-3a.69.69 0 0 0 .22-.55.723.723 0 0 0-.303-.52 1 1 0 0 0-.648-.186.962.962 0 0 0-.615.256l-3.54 3.51Z"></path></svg></i><p class="li3asHIMe05JPmtJCytG wZ4JdaHxSAhGy1HoNVja cPy9QU4brI7VQXFNPEvF">powershell</p></div><div class="CF2lgtGWtYUYmTULoX44"><button type="button" class="st68fcLUUT0dNcuLLB2_ ffON2NH02oMAcqyoh2UU MQCbz04ET5EljRmK3YpQ CPXAhl7VTkj2dHDyAYAf" data-copycode="true" role="button" aria-label="Copy Code"><svg viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg"><path fill="currentColor" fill-rule="evenodd" clip-rule="evenodd" d="M9.975 1h.09a3.2 3.2 0 0 1 3.202 3.201v1.924a.754.754 0 0 1-.017.16l1.23 1.353A2 2 0 0 1 15 8.983V14a2 2 0 0 1-2 2H8a2 2 0 0 1-1.733-1H4.183a3.201 3.201 0 0 1-3.2-3.201V4.201a3.2 3.2 0 0 1 3.04-3.197A1.25 1.25 0 0 1 5.25 0h3.5c.604 0 1.109.43 1.225 1ZM4.249 2.5h-.066a1.7 1.7 0 0 0-1.7 1.701v7.598c0 .94.761 1.701 1.7 1.701H6V7a2 2 0 0 1 2-2h3.197c.195 0 .387.028.57.083v-.882A1.7 1.7 0 0 0 10.066 2.5H9.75c-.228.304-.591.5-1 .5h-3.5c-.41 0-.772-.196-1-.5ZM5 1.75v-.5A.25.25 0 0 1 5.25 1h3.5a.25.25 0 0 1 .25.25v.5a.25.25 0 0 1-.25.25h-3.5A.25.25 0 0 1 5 1.75ZM7.5 7a.5.5 0 0 1 .5-.5h3V9a1 1 0 0 0 1 1h1.5v4a.5.5 0 0 1-.5.5H8a.5.5 0 0 1-.5-.5V7Zm6 2v-.017a.5.5 0 0 0-.13-.336L12 7.14V9h1.5Z"></path></svg>Copy Code</button><button type="button" class="st68fcLUUT0dNcuLLB2_ WtfzoAXPoZC2mMqcexgL ffON2NH02oMAcqyoh2UU MQCbz04ET5EljRmK3YpQ GnLX_jUB3Jn3idluie7R"><svg fill="none" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path fill="currentColor" fill-rule="evenodd" d="M20.618 4.214a1 1 0 0 1 .168 1.404l-11 14a1 1 0 0 1-1.554.022l-5-6a1 1 0 0 1 1.536-1.28l4.21 5.05L19.213 4.382a1 1 0 0 1 1.404-.168Z" clip-rule="evenodd"></path></svg>Copied</button></div></div><div class="mtDfw7oSa1WexjXyzs9y" style="color: var(--sds-color-text-01); font-family: var(--sds-font-family-monospace); direction: ltr; text-align: left; white-space: pre; word-spacing: normal; word-break: normal; font-size: var(--sds-font-size-label); line-height: 1.2em; tab-size: 4; hyphens: none; padding: var(--sds-space-x02, 8px) var(--sds-space-x04, 16px) var(--sds-space-x04, 16px); margin: 0px; overflow: auto; border: none; background: transparent;"><code class="language-powershell" style="color: rgb(57, 58, 52); font-family: Consolas, "Bitstream Vera Sans Mono", "Courier New", Courier, monospace; direction: ltr; text-align: left; white-space: pre; word-spacing: normal; word-break: normal; font-size: 0.9em; line-height: 1.2em; tab-size: 4; hyphens: none;"><span class="token" style="color: rgb(0, 0, 255);">param</span><span class="token" style="color: rgb(57, 58, 52);">(</span><span> </span><span> </span><span class="token">[switch]</span><span class="token" style="color: rgb(54, 172, 170);">\)SkipBlank, [string[]]\(Paths</span><span> </span><span></span><span class="token" style="color: rgb(57, 58, 52);">)</span><span> </span> <span></span><span class="token" style="color: rgb(0, 0, 255);">if</span><span> </span><span class="token" style="color: rgb(57, 58, 52);">(</span><span class="token" style="color: rgb(57, 58, 52);">-not</span><span> </span><span class="token" style="color: rgb(54, 172, 170);">\)Paths) { Write-Host “Usage: .\Count-Lines.ps1 [-SkipBlank] -Paths file1,file2” exit } \(total</span><span> = 0 </span><span></span><span class="token" style="color: rgb(0, 0, 255);">foreach</span><span> </span><span class="token" style="color: rgb(57, 58, 52);">(</span><span class="token" style="color: rgb(54, 172, 170);">\)p in \(Paths</span><span class="token" style="color: rgb(57, 58, 52);">)</span><span> </span><span class="token" style="color: rgb(57, 58, 52);">{</span><span> </span><span> </span><span class="token" style="color: rgb(0, 0, 255);">if</span><span> </span><span class="token" style="color: rgb(57, 58, 52);">(</span><span class="token" style="color: rgb(57, 58, 52);">-not</span><span> </span><span class="token" style="color: rgb(57, 58, 52);">(</span><span class="token" style="color: rgb(57, 58, 52);">Test-Path</span><span> </span><span class="token" style="color: rgb(54, 172, 170);">\)p -PathType Leaf)) { Write-Host “Skipped: \(p</span><span class="token" style="color: rgb(163, 21, 21);"> (not a file)"</span><span> </span><span> </span><span class="token" style="color: rgb(0, 0, 255);">continue</span><span> </span><span> </span><span class="token" style="color: rgb(57, 58, 52);">}</span><span> </span><span> </span><span class="token" style="color: rgb(0, 0, 255);">if</span><span> </span><span class="token" style="color: rgb(57, 58, 52);">(</span><span class="token" style="color: rgb(54, 172, 170);">\)SkipBlank) { \(count</span><span> = </span><span class="token" style="color: rgb(57, 58, 52);">Get-Content</span><span> </span><span class="token" style="color: rgb(57, 58, 52);">-</span><span>Path </span><span class="token" style="color: rgb(54, 172, 170);">\)p | Where-Object { \(_</span><span class="token" style="color: rgb(57, 58, 52);">.</span><span>Trim</span><span class="token" style="color: rgb(57, 58, 52);">(</span><span class="token" style="color: rgb(57, 58, 52);">)</span><span> </span><span class="token" style="color: rgb(57, 58, 52);">-ne</span><span> </span><span class="token" style="color: rgb(163, 21, 21);">''</span><span> </span><span class="token" style="color: rgb(57, 58, 52);">}</span><span> </span><span class="token" style="color: rgb(57, 58, 52);">|</span><span> </span><span class="token" style="color: rgb(57, 58, 52);">Measure-Object</span><span> </span><span class="token" style="color: rgb(57, 58, 52);">|</span><span> </span><span class="token" style="color: rgb(57, 58, 52);">Select-Object</span><span> </span><span class="token" style="color: rgb(57, 58, 52);">-</span><span>ExpandProperty Count </span><span> </span><span class="token" style="color: rgb(57, 58, 52);">}</span><span> </span><span class="token" style="color: rgb(0, 0, 255);">else</span><span> </span><span class="token" style="color: rgb(57, 58, 52);">{</span><span> </span><span> </span><span class="token" style="color: rgb(54, 172, 170);">\)count = (Get-Content -Path \(p</span><span> </span><span class="token" style="color: rgb(57, 58, 52);">|</span><span> </span><span class="token" style="color: rgb(57, 58, 52);">Measure-Object</span><span class="token" style="color: rgb(57, 58, 52);">)</span><span class="token" style="color: rgb(57, 58, 52);">.</span><span>Count </span><span> </span><span class="token" style="color: rgb(57, 58, 52);">}</span><span> </span><span> </span><span class="token" style="color: rgb(57, 58, 52);">Write-Host</span><span> </span><span class="token" style="color: rgb(163, 21, 21);">"</span><span class="token" style="color: rgb(54, 172, 170);">\)p: \(count</span><span class="token" style="color: rgb(163, 21, 21);">"</span><span> </span><span> </span><span class="token" style="color: rgb(54, 172, 170);">\)total += \(count</span><span> </span><span></span><span class="token" style="color: rgb(57, 58, 52);">}</span><span> </span><span></span><span class="token" style="color: rgb(57, 58, 52);">Write-Host</span><span> </span><span class="token" style="color: rgb(163, 21, 21);">"Total: </span><span class="token" style="color: rgb(54, 172, 170);">\)total”
Notes:
- Get-Content streams by default; for very large files, consider -ReadCount parameter tuning.
Tips and Extensions
- Add recursion to process directories (find/xargs in Bash, os.walk in Python, Get-ChildItem -Recurse in PowerShell).
- Add file-type filters (extensions) to skip binaries.
- Output in CSV or JSON for integration with other tools.
- Combine with git to count lines changed in commits or branches.
Quick Comparison
- Bash: best for Unix shells and piping; fastest for simple counts.
- Python: portable and easy to extend; good balance of readability and power.
- PowerShell: native on Windows and cross-platform with PowerShell Core.
Pick the script that fits your environment, save it, and you’ll have a quick line-counter ready in seconds.