0

I'm trying to teach myself bash scripting and I'm trying to learn how to alternate between the compound test command ([[ ]]) and test ([ ]).

Using the book I'm learning from, I'm trying to recreate the following program using test instead of [[ ]].

#!/bin/bash

# read-validate: valiate input

invalid_input()
{
    echo "Invalid input '$REPLY'" >&2
    exit 1
}

read -p "Enter a single item > "


#input is empty (invalid)
[ -z $REPLY ] && invalid_input

#input is multiple items
(( $(echo $REPLY | wc -w) > 1 )) && invalid_input

# is input a valid filename?
if [[ $REPLY=~ ^[-[:alnum:]\._]+$; then
    echo "'$REPLY is a valid filename."
    if [ -e $REPLY ]; then
        echo "And file '$REPLY' exists."
    else
        echo "However, file '$REPLY' does not exist."
    fi

    #is input a floating point number?
    if [[ $REPLY =~ ^-?[[:digit:]]*\.[[:digit:]]+$ ]]; then
        echo "'$REPLY' is a floating point number."
    else
        echo "'$REPLY' is not a floating point number."
    fi

    # is input an integer?
    if [[ $REPLY =~ ^-?[[:digit:]]+$ ]]; then
        echo "'$REPLY' is an integer."
    else
        echo "'$REPLY' is not an integer."
    fi
else
    echo "The string '$REPLY' is not a valid filename."
fi

My problem begins with trying to use regular expressions to search for floating point numbers.

#!/bin/bash

# read-validate: valiate input

invalid_input()
{
    echo "Invalid input '$REPLY'" >&2
    exit 1
}

read -p "Enter a single item > "
valid_fname=$(egrep ^[-[:alnum:]\._]+$ <<< "$REPLY" | wc -m)
valid_float=$(egrep ^-?[[:digit:]]*\.[[:digit:]]+$ <<< "$REPLY" | wc -w)

#input is empty (invalid)
[ -z $REPLY ] && invalid_input

#input is multiple items
(( $(echo $REPLY | wc -w) > 1 )) && invalid_input

# is input a valid filename?
if [ "$valid_fname" -gt 0 ]; then
    echo "'$REPLY is a valid filename."
    if [ -e $REPLY ]; then
        echo "And file '$REPLY' exists."
    else
        echo "However, file '$REPLY' does not exist."
    fi

    #is input a floating point number?
    if [ "$valid_float" -gt 0 ]; then
    #if [[ $REPLY =~ ^-?[[:digit:]]*\.[[:digit:]]+$ ]]; then
        echo "'$REPLY' is a floating point number."
    else
        echo "'$REPLY' is not a floating point number."
    fi
else
    echo "The string '$REPLY' is not a valid filename."
fi

For some reason, egrep doesn't bother looking for decimals points even though \. is included in the regular expression. This results in the program picking up integers and validating them as floating point numbers. Oddly enough, single digits are not validated as floating points (0-9). But integers in the double digits and onwards are validated as floating points. I have no idea why this happens.

alexbclay
  • 1,389
  • 14
  • 19
Alphatron
  • 83
  • 2
  • 10
  • 2
    you need single quotes around your egrep regexes, otherwise bash parses the `\.` and only `.` gets to egrep. double digit integers match because `egrep .[[:digit:]]+`. – webb Sep 23 '16 at 05:42
  • Thanks @webb! That worked! So without single quotes, egrep interprets `.` as the "any character" expression? – Alphatron Sep 23 '16 at 15:18
  • Without quotes, `egrep` doesn't receive the backslash, because it is being processed and discarded by the shell. Marking as duplicate of a question which explains this in more detail. – tripleee Sep 28 '16 at 16:03

0 Answers0