omar180791
omar180791

Reputation: 39

compare regex with grep output - bash script

I'm trying to find the word "PASS_MAX_DAYS" in a file using grep grep "^PASS_MAX_DAYS" /etc/login.defs then I save it in a variable and compare it to a regular expression that has the value 90 or less.

regex = "PASS_MAX_DAYS\s*([0-9]|[1-8][0-9]|90)"

grep output is: PASS_MAX_DAYS 120

so my function should print a fail, however it matches:

function audit_Control () {

    if [[ $cmd =~ $regex ]]; then
        echo match
    else
        echo fail
    fi
}
cmd=`grep "^PASS_MAX_DAYS" /etc/login.defs`
regex="PASS_MAX_DAYS\s*([0-9]|[1-8][0-9]|90)"
audit_Control "$cmd" "$regex"

Upvotes: 0

Views: 497

Answers (2)

Stephen P
Stephen P

Reputation: 14800

The problem is that the bash test [[ using the regex match operator =~ does not support the common escapes such as \s for whitespace or \W for non-word-characters.

It does support posix predefined character classes, so you can use [[:space:]] in place of \s

Your regex would then be:
regex="PASS_MAX_DAYS[[:space:]]*([0-9]|[1-8][0-9]|90)"

You may want to add anchors ^ and $ to ensure a whole-line match, then the regex is
regex="^PASS_MAX_DAYS[[:space:]]*([0-9]|[1-8][0-9]|90)$"

Without the end-of-line anchor you could match lines that have trailing numbers after the match, so PASS_MAX_DAYS 9077 would match PASS_MAX_DAYS 90 and the trailing "77" would not prevent the match.

This answer also has some very useful information about bash's [[ ]] construction with the =~ operator.

Upvotes: 1

lucasgrvarela
lucasgrvarela

Reputation: 351

I believe you have a problem with your regex, please try that version:

PASS_MAX_DAYS\s*([0-9]|[1-8][0-9]|90)$

[lucas@lucasmachine ~]$ cat test.sh 
#!/bin/bash

function audit_Control () {

    if [[ $cmd =~ $regex ]]; then
        echo match
    else
        echo fail
    fi
}
regex="PASS_MAX_DAYS\s*([0-9]|[1-8][0-9]|90)$"
audit_Control "$cmd" "$regex"
[lucas@lucasmachine ~]$ export cmd="PASS_MAX_DAYS 123"
[lucas@lucasmachine ~]$ ./test.sh 
fail
[lucas@lucasmachine ~]$ export cmd="PASS_MAX_DAYS 1"
[lucas@lucasmachine ~]$ ./test.sh 
match

I can explain the problem was the other regex was not checking the end of line, so, your were matching "PASS_MAX_DAYS 1"23 so 23 were not being "counted" to your regex. Your regex was really matching part of the text.. Now with the end of line it should match exactly 1 digit find a end of line, or [1-8][0-9] end of line or 90 end of line.

Upvotes: 0

Related Questions