Bash script, "flash cards" for Spanish vocabulary I use this bash script to review over vocabulary with my dental Spanish class. The script works great for me. However, I am wondering what other ways the same thing could be done. How could it be more efficient? Perhaps the script could me made more readable? Maybe other areas could be made more proper or elegant? If I have done something well, then that feedback too is appreciated. I am not particularly interested in adding in checks/tests of the formatting of my vocabulary sheet or checking to make sure the file exists. The comments have my English translations of the Spanish in the script. 

This script reads each line of the vocabulary file from the top to the bottom and tests whether the user knows how to say the equivalent in Spanish. It is formatted like this, English: SpanishOpt1, SpanishOpt2, SpanishOpt3. Any of the options between commas could count as correct. 

This is a sample of what a vocab file looks like:


floor of the mouth: piso de la boca
cheek: mejilla, cachete
throat: garganta
change in color: cambio en color, cambio de color
taste buds: bulbos gustativos
growth: crecimiento
bruise: moretón, cardenal, magulladura, moradura, contusión



Here is the script:

#!/bin/bash

read -r -p "1 - evaluación oral
2 - radiografía
Elige uno: " opt
# Choose one.

clear

if ! [[ "$opt" =~ ^[1-2]$ ]]; then
    # That is not an option. Choose 1 or 2. 
    echo "Eso no es una opción. Elige 1 o 2."
    exit 1
fi

fname=("" "evaluación-oral-vocabulario.txt" "radiografía-vocabulario.txt")
file="/home/brock/2-Work/Dental/${fname[$opt]}"
vocab_items=$(wc -l &lt; "$file")
line_num=1
num_right=0

until (("$line_num" &gt; "$vocab_items")); do
    vocab_item=$(head -n"$line_num" "$file" | tail -n1)
    english=$(echo "$vocab_item" | cut -d: -f1)
    spanish=$(echo "$vocab_item" | cut -d: -f2 | sed 's/ //')
    plural_options=$(echo "$spanish" | grep ,)
    plural_vocab_item=$(echo "$spanish" | cut -d, -f1 | wc -w) 
    if [ -n "$plural_options" ] || (("$plural_vocab_item" &gt; "1")); then
        # The "s" is to make the subject below "Las palabras" plural if needed. The "n" is for the plural verb conjugation.
        s="s"; n="n"
    else    
        s=""; n=""
    fi
    # How do you say ... in Spanish?
    read -r -p "¿Cómo se dice \"$english\" en español? " r
    answer_check=$(echo "_${spanish}_" | sed 's/, /_/g' | grep "_${r}_")
    # The "y" means "and" which is added before the last item in a list with no serial comma.
    spanish_feedback=$(echo "$spanish" | sed 's/\(.*\),/\1 y/')
    if [ -n "$answer_check" ]; then
        # You are correct. The word(s) ... mean ...
        echo -e "\tTienes razón. La$s palabra$s \"$spanish_feedback\" quiere$n decir \"$english\".\n"
        ((num_right++)) 
    else    
        # You are not correct. The word(s) ... mean ...
        echo -e "\tNo tienes razón. La$s palabra$s \"$spanish_feedback\" quiere$n decir \"$english\".\n"
        pair_wrong[$line_num]="$vocab_item\n"
    fi  
    ((line_num++))
done

# You know ... out of ... terms overall.
echo "Tú sabes $num_right de $vocab_items términos en total."
if [ -z "${pair_wrong[*]}" ]; then
    # Incredible! One hundred percent!
    echo "¡Increíble! ¡Cien por ciento!"
else
    # You have to work more on:
    echo -e "Tienes que trabajar más en:\n ${pair_wrong[*]}"
fi
I haven't used or reviewed bash script for ever, so I'm just going to give a few comments:


Your script reads nicely, and even though I don't know spanish, there are some comments explaining the vital parts.
I think the script could benefit from a little more spacing, so that the various sections stood out a little more. The top half is better than the bottom half.
The variable names are good and helpful
However there are two code smells that I see:


Each time you set vocab_item you're re-reading the file. So at end of script you've read the file \$N\$ times, where \$N\$ is the number of lines
Each time you set english and spanish to trigger a new call to cut.



Reading the main file once

After a little searching I found this thread on SO:Looping through the content of a file in bash. The accepted answers uses the following construct:

while read p; do
  echo $p
done &lt;peptides.txt


This would allow for reading the file just once, but you'll need to change a little of your logic related to counting the correct number of answers. 

Splitting a line into an array

Another search, and another SO thread: Split string into an array in bash. This one to avoid the calls to cut.

IFS=', ' read -r -a parts &lt;&lt;&lt; "$vocab_item"
english="${parts[0]}"
spanish="${parts[1]}"


Hope this helps to some extent.