Bash script that counts the characters, frequency, and percentage of letters in Spanish sonnets
The right tool for the job

Nice script! But Bash is not well-suited for this kind of computation.
Bash is good as glue code,
connecting different applications, bridging the gap,
doing simple stuff.
The task at hand would have been better written in proper programming language, for example Python.

Usability

When the first argument is missing or empty,
the script exits with an error message: "Script needs an argument.".
What kind of argument? It would be better if it gave a hint, for example:

if [ $# = 0 ]; then
    echo "Usage: $0 file"
    exit 1
fi


This gives a hint that the script requires a file argument.

I also changed the condition from -z "$1" to $# = 0.
The former means "first argument is missing or empty",
the latter means "script has no arguments".
This is probably closer to your intention.

Creating empty files

A simple way to create an empty file:

&gt; "$fname"


Don't use flags of echo

The flags of echo are not portable, for example echo -n.
Try to avoid as much as possible.
You can use printf instead.
On the other hand, echo without any flags is fine.

Counting characters

In your input I don't see multibyte characters.
If you don't need to support such characters,
then you could use native Bash syntax ${#chars} to get the length of $chars,
no need for wc -m.

Writing to "$fname"

The script passes some text to | tee -a "$fname" at multiple places:


header
loop output


inside the loop, blank line after the letter u -> this one looks like a bug

footer


Writing | tee ... multiple times is tedious and error-prone.
You could group commands to simplify:

{
    echo header ...
    for ...
    echo footer ...
} | tee -a "$fname"


Probably you can drop the -a from tee to truncate the file,
and that will also allow you to remove the manual truncation at the beginning of the script.