2

I need your help in identifying my problem below,

My intention is to loop the input of the values while at the same time checking the input value if its [0-9] then saves it to a file then sorts the output of it.

My problem is that, whenever i run the script, the values retained as 1 2 3 4 5 not the one that i have inputted, can you help me on this ? i think there is a problem in my variable declaration in the conditional statements, but i dont know any workaround on it.

#!/bin/bash -x

echo > save.txt
validnum='0-9'

   for ((i=1;i<=5;i++))
   do
    read -p "Please enter number $i: " num_$i
    if [[ ! $num_$i =~ [^$validnum$] ]] && [[  $num_$i == "" ]]
    then
            echo "Input numbers have been validated.."
            echo $num_$i >> save.txt
    else
            echo "INVALID CHARACTERS IDENTIFIED.."
            echo "Please review your Input Values"
            exit 0
    fi
done
echo "Sorting values.."
echo "Below are the sorted values"
echo `cat save.txt | sort -n`

here is the expanded version whenever i ran the script.

+ echo
+ validnum=0-9
+ (( i=1 ))
+ (( i<=5 ))
+ read -p 'Please enter number 1: ' num_1
Please enter number 1:
+ [[ ! 1 =~ [^0-9$] ]]
+ [[ ! 1 == '' ]]
+ echo 'Input numbers have been validated..'
Input numbers have been validated..
+ echo 1
+ (( i++ ))
+ (( i<=5 ))
+ read -p 'Please enter number 2: ' num_2
Please enter number 2:
+ [[ ! 2 =~ [^0-9$] ]]
+ [[ ! 2 == '' ]]
+ echo 'Input numbers have been validated..'
Input numbers have been validated..
+ echo 2
+ (( i++ ))
+ (( i<=5 ))
+ read -p 'Please enter number 3: ' num_3
Please enter number 3:
+ [[ ! 3 =~ [^0-9$] ]]
+ [[ ! 3 == '' ]]
+ echo 'Input numbers have been validated..'
Input numbers have been validated..
+ echo 3
+ (( i++ ))
+ (( i<=5 ))
+ read -p 'Please enter number 4: ' num_4
Please enter number 4:
+ [[ ! 4 =~ [^0-9$] ]]
+ [[ ! 4 == '' ]]
+ echo 'Input numbers have been validated..'
Input numbers have been validated..
+ echo 4
+ (( i++ ))
+ (( i<=5 ))
+ read -p 'Please enter number 5: ' num_5
Please enter number 5:
+ [[ ! 5 =~ [^0-9$] ]]
+ [[ ! 5 == '' ]]
+ echo 'Input numbers have been validated..'
Input numbers have been validated..
+ echo 5
+ (( i++ ))
+ (( i<=5 ))
+ echo 'Sorting values..'
Sorting values..
+ echo 'Below are the sorted values'
Below are the sorted values
++ cat save.txt
++ sort -n
+ echo 1 2 3 4 5
1 2 3 4 5
7
  • 2
    You cannot define dynamic variables like you did with num_$i. Probably best to use an array Commented May 3, 2017 at 11:46
  • Or just don't use a dynamic variable at all. Just use num as a variable on its own. Can't see the need for a dynamic variable in this instance. Commented May 3, 2017 at 11:55
  • any suggestions in replacing the dynamic variable ? i haven't tried Arrays yet , im currently reading about it though Commented May 3, 2017 at 11:58
  • 2
    Technically, you could use indirect parameter expansion to access the variable, although it is clumsy. tmp=num_$i; if [[ ! ${!tmp} =~ ^$validnum$ ]] && [[ ${!tmp} == "" ]]. Better to recognize that you don't need separate variables for each iteration of the loop. Commented May 3, 2017 at 12:12
  • 1
    @ZaCkDelaCruz, Here why the statement [[ ! $num_$i =~ [^$validnum$] ]] can't work? Because $num_$i is expanded two variables num_ and i. Because the name num_ is a valid variable name in Bash. So it will parse they are two variables. But if you enclosed it with brackets like ${num_$i} will not work. Because it will complain bad substitution error. If you want it work, you can use Indirect References. var="num_$i" ; echo ${!var} will work. Please refer to Bash dynamic variable names. Commented May 3, 2017 at 12:17

1 Answer 1

2

I think you just need the following,

validnum='[0-9]'

read -p "Please enter number $i: " num

if [[ $num =~ ^$validnum{1}$ ]]; then
# rest of the code

to match a single digit from 0-9. Remember I have moved the bracket expressions inside the variable validnum which is more readable than your original version. Plugging this snippet in to your code should fix your problem.

And as discussed over in the comments, you don't need to use the dynamic variables for this requirement of yours.


OP had asked for the explanation of the regex,

RegEx demo

Quoting from the above regular expressions page, explaining the regex ^[0-9]{1}$

^ asserts position at start of the string

Match a single character present in the list below [0-9]{1}

{1} Quantifier — Matches exactly one time (meaningless quantifier)

0-9 a single character in the range between 0 (ASCII 48) and 9 (ASCII 57) (case sensitive)

$ asserts position at the end of the string, or before the line terminator right at the end of the string

Sign up to request clarification or add additional context in comments.

2 Comments

Thank you for the help, i followed the previous comments about the dynamic variable and got the values correct. what i dont understand is the 1 in ^$validnum{1}$ .. what does it do ? is it the length of the input value ?
@ZaCkDelaCruz: See my update, see if it is helpful to you

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.