Home > Blockchain >  How to use ^[]$ format to compare string with numbers greater than 9?
How to use ^[]$ format to compare string with numbers greater than 9?

Time:07-28

Say I have a simple statement:

read number

[[ ! $number =~ ^[1-3245][,][1-3245]$ ]] && echo "Not a valid number."

I want to check to see if the number is between 1-3245. But it seems like it's looking for a number between 1 and 3 for the first integer, then 2,4,5. How do get this to check if the number entered looks like 1-3245,1-3245? I've tried with {} and .. instead of - But still no go. I'd like to avoid a crazy long string .

*Edit I should be more specific here. I am looking to check user input and match it to a desired format; that format being 'int,int,int....' where int is = an integer between 1-3245. I hope this makes sense.

CodePudding user response:

Since the base question is to write on regex to get range of numbers. So keeping it as my first solution here, for future readers help.

1st solution(using regex): With your shown samples and attempts you can have your bash script like as follows, please make sure to give script proper permissions and run it then.

Also here is the Online demo for used regex.

#!/bin/bash

echo "Enter a number:"
read number

if [[ $number =~ ^([1-9]|[1-9][0-9]{1,2}|1[0-9]{3}|2[0-9]{3}|[3][0-1][0-9]{2}|32[0-3][0-9]|324[0-5])$ ]]
then
    echo "Number $number is between 1 to 3245"
else
    echo "Please enter number in range of 1 to 3245..."
fi

Explanation:

  • Firstly printing message on screen by echo command for user, its always a Good practice to put a proper user-friendly message on screen. Here in this case its "Please enter a number:"
  • Using read command to get value from user and save it into number shell variable.
  • Then using if condition to match value of variable with regex^([1-9]|[1-9][0-9]{1,2}|1[0-9]{3}|2[0-9]{3}|[3][0-1][0-9]{2}|32[0-3][0-9]|324[0-5])$, remember bash doesn't support non-capturing groups here.
  • if condition is TRUE then print eg: Number 2980 is between 1 to 3245 else print eg: Please enter number in range of 1 to 3245...


2nd solution: using awk and without regex here.

#!/bin/bash

echo "Enter a number:"
read number

val=$(echo $number | awk '$0 0==$0 && ($0>=1 && $0<=3245)')

if [[ -n "$val"  ]]
then
    echo "Number $number is between 1 to 3245"
else
    echo "Please enter number in range of 1 to 3245..."
fi

CodePudding user response:

Assuming your criteria is: integer between 1 and 3245 (included), comma, integer between 1 and 3245 (included), you can use a mixture of regular expression and arithmetic:

$ foo() {
  [[ "$1" =~ ^([0-9]*),([0-9]*)$ ]] || return 1
  a=${BASH_REMATCH[1]}; b=${BASH_REMATCH[2]}
  (( a >= 1 && a <= 3245 && b >= 1 && b <= 3245 ))
}
$ foo 2,2 && echo "OK" || echo "Not a valid number."
OK
$ foo 2,4000 && echo "OK" || echo "Not a valid number."
Not a valid number.
$ foo 2,bar
Not a valid number.

If the number of comma-separated integers is unknown (but minimum one) and you want to use only bashyou will need a loop:

$ foo() {
  n="$1"
  while [[ "$n" =~ ^([0-9] )((,[0-9] )*)$ ]] || return 1; do
    (( BASH_REMATCH[1] < 1 || BASH_REMATCH[1] > 3245 )) && return 1
    n="${BASH_REMATCH[2]#,}"
    [[ -z "$n" ]] && return 0
  done
  return 1
}
$ foo 2,2,2,2,2 && echo "OK" || echo "Not a valid number."
OK
$ foo 2,2,4000,2,2 && echo "OK" || echo "Not a valid number."
Not a valid number.
$ foo 2,2,bar,2,2 && echo "OK" || echo "Not a valid number."
Not a valid number.

But if you can also use external utilities GNU awk would be a bit simpler:

$ foo() {
  awk -F, 'NR > 1 { exit 1 } {
    for(i=1; i<NF; i  )
      if($i !~ /^[0-9] $/ || $i < 1 || $i > 3245) exit 1
  }' <<< "$1"
}
$ foo 2,2,2,2,2 && echo "OK" || echo "Not a valid number."
OK
$ foo 2,2,4000,2,2 && echo "OK" || echo "Not a valid number."
Not a valid number.
$ foo 2,2,2,bar,2 && echo "OK" || echo "Not a valid number."
Not a valid number.
  •  Tags:  
  • bash
  • Related