<article>
<h2 id="overview">Overview</h2>
<p>Have you ever written a Bash script (or any shell script) where you
generate a message like <code>'Found 42 files'</code> and the day comes
when it reports <code>'Found 1 files'</code>?</p>
<p>Have you been irritated by this? I have, and I go to lengths to deal
properly with (English) plurals in my Bash scripts.</p>
<h2 id="method-1">Method 1</h2>
<p>The simplest solution would be to use an <code>'if'</code>
statement:</p>
<pre><code>if [[ $fcount -eq 1 ]]; then
    echo &quot;Found 1 file&quot;
else
    echo &quot;Found $fcount files&quot;
fi</code></pre>
<p>This works, but to have to do it for every message would be a
pain!</p>
<h2 id="method-2">Method 2</h2>
<p>The next approach to this problem might be to write a Bash
function.</p>
<pre><code>pluralise () {
    local singular=&quot;${1}&quot;
    local plural=&quot;${2}&quot;
    local count=&quot;${3}&quot;

    if [[ $count -eq 1 ]]; then
        echo &quot;$singular&quot;
    else
        echo &quot;$plural&quot;
    fi
}</code></pre>
<p>This can be called as follows:</p>
<pre><code>$ i=1; echo &quot;Found $i $(pluralise &quot;file&quot; &quot;files&quot; $i)&quot;
Found 1 file
$ i=42; echo &quot;Found $i $(pluralise &quot;file&quot; &quot;files&quot; $i)&quot;
Found 42 files</code></pre>
<p>The string being displayed with <code>echo</code> contains a command
substitution (<code>'$(command)'</code>) which returns
<code>'file'</code> or <code>'files'</code> depending on the value
given.</p>
<p>The first two arguments can be more complex than plain strings:</p>
<pre><code>$ i=1; echo &quot;There $(pluralise &quot;is 1 light&quot; &quot;are $i lights&quot; $i)&quot;
There is 1 light
$ i=4; echo &quot;There $(pluralise &quot;is 1 light&quot; &quot;are $i lights&quot; $i)&quot;
There are 4 lights</code></pre>
<p>The <a
href="https://hackerpublicradio.org/eps/hpr3722/pluralise.sh"><code>pluralise</code>
function</a> is available for download.</p>
<h2 id="method-3">Method 3</h2>
<p>The GNU project has developed a set of utilities called the <em>GNU
gettext utilities</em> consisting of tools and <a
href="https://www.gnu.org/software/gettext/">documentation</a> for
translation. This is a large subject which is not suitable for a short
HPR episode such as this one.</p>
<p>Among the tools is <code>'ngettext'</code> which performs the
function we have been discussing - choosing among plural forms. It also
implements translations if desired (and translation files are provided
as part of the software being developed).</p>
<p>We will not discuss the translation topic here, but the choice of
plurals is something that can be used in Bash scripts.</p>
<p>The <code>'ngettext'</code> tool takes three mandatory
parameters:</p>
<ul>
<li><em>MSGID</em> - the singular form of the text</li>
<li><em>MSGID-PLURAL</em> - the plural form of the text</li>
<li><em>COUNT</em> - the value used to make the singular/plural
choice</li>
</ul>
<p>There are other optional parameters and options but they are not
relevant here.</p>
<p>The tool can be used in exactly the same way as the
<code>'pluralise'</code> example above.</p>
<pre><code>$ i=1; echo &quot;There $(ngettext &quot;is 1 light&quot; &quot;are $i lights&quot; $i)&quot;
There is 1 light
$ i=4; echo &quot;There $(ngettext &quot;is 1 light&quot; &quot;are $i lights&quot; $i)&quot;
There are 4 lights</code></pre>
<p>Whether you use this or a Bash function is your choice.</p>
<h2 id="conclusion">Conclusion</h2>
<p>I have been using <code>ngettext</code> in my scripts since I
discovered it. If you also need to provide messages in your projects in
other languages then this might be a good idea.</p>
<p>I admit that my understanding of the GNU <code>gettext</code> project
is superficial, so, on reflection it might be better to use a Bash
function, since I don’t currently need all of the features GNU
<code>gettext</code> provides.</p>
<h2 id="links">Links</h2>
<ul>
<li><a href="https://hackerpublicradio.org/eps/hpr3722/pluralise.sh">The
<code>pluralise</code> function</a>. Either add it to the script you’re
developing or use the <code>'source'</code> command to load it.</li>
<li><a href="https://www.gnu.org/software/gettext/">GNU
<code>gettext</code> utilities</a>, part of the <em>GNU Translation
Project</em>.
<ul>
<li><a
href="https://www.gnu.org/software/gettext/manual/html_node/ngettext-Invocation.html">Documentation
specific to <code>ngettext</code></a></li>
</ul></li>
</ul>
</article>
