Home > Blockchain >  Check if a string contains valid pattern in Bash
Check if a string contains valid pattern in Bash

Time:07-26

I have a file a.txt contains a string like: Axxx-Bxxxx Rules for checking if it is valid or not include:

  • length is 10 characters.
  • x here is digits only.

Then, I try to check with:

#!/bin/bash
exp_len=10;
file=a.txt;
msg="checking string";
tmp="File not exist";

echo $msg;
if[ -f $file];then
    tmp=$(cat $file);
    if[[${#tmp} != $exp_len ]];then
        msg="invalid length";
    elif [[ $tmp =~ ^[A[0-9]{3}-B[0-9]{4}]$]];then
        msg="valid";
    else
        msg="invalid";
    fi
else
    msg="file not exist";
fi
echo $msg;

But in valid case it doesn't work... Is there someone help to correct me? Thanks :)

CodePudding user response:

Other than the regex fix, your code can be refactored as well, moreover there are syntax issues as well. Consider this code:

file="a.txt"
msg="checking string"
tmp="File not exist"

echo "$msg"

if [[ -f $file ]]; then
    s="$(<$file)"
    if [[ $s =~ ^A[0-9]{3}-B[0-9]{4}$ ]]; then
        msg="valid"
    else
        msg="invalid"
    fi
else
    msg="file not exist"
fi

echo "$msg"

Changes are:

  • Remove unnecessary cat
  • Use [[ ... ]] when using bash
  • Spaces inside [[ ... ]] are required (your code was missing them)
  • There is no need to check length of 10 as regex will make sure that part as well
  • As mentioned in comments earlier correct regex should be ^A[0-9]{3}-B[0-9]{4}$ or ^A[[:digit:]]{3}-B[[:digit:]]{4}$

CodePudding user response:

Note that a regex like ^[A[0-9]{3}-B[0-9]{4}]$ matches

  • ^ - start of string
  • [A[0-9]{3} - three occurrences of A, [ or a digit
  • -B - a -B string
  • [0-9]{4} - four digits
  • ] - a ] char
  • $ - end of string.

So, it matches strings like [A[-B1234], [[[-B1939], etc.

Your regex checking line must look like

if [[ $tmp =~ ^A[0-9]{3}-B[0-9]{4}$ ]];then

See the online demo:

#!/bin/bash
tmp="A123-B1234";
if [[ $tmp =~ ^A[0-9]{3}-B[0-9]{4}$ ]];then
        msg="valid";
    else
        msg="invalid";
fi
echo $msg;

Output:

valid

CodePudding user response:

Using just grep might be easier:

$ echo A123-B1234 > valid.txt
$ echo 123 > invalid.txt
$ grep -Pq 'A\d{3}-B\d{4}' valid.txt && echo valid || echo invalid
valid
$ grep -Pq 'A\d{3}-B\d{4}' invalid.txt && echo valid || echo invalid
invalid

CodePudding user response:

With your shown samples and attempts, please try following code also.

#!/bin/bash
exp_len=10;
file=a.txt;
msg="checking string";
tmp="File not exist";

if [[ -f "$file" ]]
then
    echo "File named $file is existing.."
    awk '/^A[0-9]{3}-B[0-9]{4}$/{print "valid";next} {print "invalid"}' "$file"
else
    echo "Please do check File named $file is not existing, exiting from script now..."
    exit 1;
fi

OR In case you want to check if line in your Input_file should be 10 characters long(by seeing OP's attempted code's exp_len shell variable) then try following code, where an additional condition is also added in awk code.

#!/bin/bash
exp_len=10;
file=a.txt;
msg="checking string";
tmp="File not exist";

if [[ -f "$file" ]]
then
    echo "File named $file is existing.."
    awk -v len="$exp_len" 'length($0) == len && /^A[0-9]{3}-B[0-9]{4}$/{print "valid";next} {print "invalid"}' "$file"
else
    echo "Please do check File named $file is not existing, exiting from script now..."
    exit 1;
fi

NOTE: I am using here -f flag to test if file is existing or not, you can change it to -s eg: -s "$file" in case you want to check file is present and is of NOT NULL size.

  • Related