Add license to beginning of files I'm trying to come up with a script that will add license headers to certain files (depending on extension). My Bash is very average, so any guidance would be much appreciated.

I'm not quite sure what to ask for except for whether I'm making any gross mistakes.

#!/usr/bin/env bash

set -euo pipefail

shopt -s globstar nullglob extglob

lineone="Copyright (c) 2015 Acme Corp, LLC."
linetwo="Unauthorized copying of this file via any medium is strictly prohibited."
linethree="Written by John Doe &lt;j@acme.com&gt;, July 2015" # etc.

printf "// %s
// %s
// %s\n\n" "$lineone" "$linetwo" "$linethree" &gt; "/tmp/$USER-license-go"

printf "{{/*
%s
%s
%s
*/}}\n\n" "$lineone" "$linetwo" "$linethree" &gt; "/tmp/$USER-license-gohtml"

printf "# %s
# %s
# %s\n\n" "$lineone" "$linetwo" "$linethree" &gt; "/tmp/$USER-license-shell"


typ=""
for f in **/*; do
    if [[ -f $f ]]; then
        if ! grep -q Copyright "$f"; then
            case "$f" in
                *.go             ) typ="go"      ;;
                *.gohtml         ) typ="gohtml"  ;;
                @(*.bash|*.conf) ) typ="shell"   ;;
                *                ) continue      ;;
            esac

            cat "/tmp/$USER-license-"$typ "$f" | sponge "$f"
        fi
    fi
done
This is quite fine. I have a few tips though.

Don't repeat yourself

The base path "/tmp/$USER-license-" appears many times.
This is error prone,
and it makes it difficult to change later.
It would be better to put this in a variable and reuse it everywhere.

here-document instead of printf

Instead of the printf statements to generate the headers,
here-documents would be simpler and better, for example:

cat &lt;EOF &gt;"$BASEPATH"-go
// $lineone
// $linetwo
// $linethree

EOF


Tabulation

Aligning things vertically like this may look nice at first:


case "$f" in
    *.go             ) typ="go"      ;;
    *.gohtml         ) typ="gohtml"  ;;
    @(*.bash|*.conf) ) typ="shell"   ;;
    *                ) continue      ;;
esac



The problem with this is if you want to change something later.
For example, I don't really see the purpose of the @(...) there,
so I would like to simplify:

case "$f" in
    *.go             ) typ="go"      ;;
    *.gohtml         ) typ="gohtml"  ;;
    *.bash|*.conf ) typ="shell"   ;;
    *                ) continue      ;;
esac


But that broke the formatting. What do I do now?
Add padding to line up the ) that is now out of line?
Or update the other lines?
The second option is not great, because I have to change many lines just because I changed one.
Just thinking about this is actually a waste of time.

Considering possible future changes,
I suggest to avoid this kind of writing style,
and stick to good old simple:

case "$f" in
    *.go) typ="go" ;;
    *.gohtml) typ="gohtml" ;;
    *.bash|*.conf) typ="shell" ;;
    *) continue ;;
esac


Alternative to sponge

I didn't know about sponge and moreutils,
I'm really glad your has question lead me to discover these gems.

On the other hand, unfortunately sponge is not a standard command,
and may not be readily available. Here's an alternative using GNU sed:

license="$BASEPATH"-$typ
sed -i -e "1r$license" -e '1{h;d}' -e '2{x;G}' "$f"