Issue
I am trying to check if every line in a file matches my pattern (4 characters followed by 4 digits). I tried using GREP with -x -P -v -q options so it returns 1 if my file doesn't match the requirements. I expect it to return nothing in case the file is correct, but it returns nothing even if the file has an error. $4 is my input file. My code is:
if [ -f $4 ] && [ `grep -q -P -x -v [[a-z]x{4}/[\dx{4}] $4` ]
then
echo "error"
exit 1
fi
input example: bmkj2132 ahgc3478 (no uppercase)
Solution
Don't check the output of grep
, check its exit code.
if [ -f "$4" ] && grep -q ...
Note the double quotes around $4
- otherwise a file name containing whitespace will break the script.
Also, single quote the regex. Square brackets are special in bash and you don't want the regex to suddenly change (expand) when a random filename exists.
Also note that x
doesn't mean "times" (under -e, -E, -P neither). The quantifier just follows the quantified with no operator in between:
echo abcd1234 | grep -xP '[a-z]{4}\d{4}'
So, the full condition should be
if [ -f "$4" ] && grep -qvxP '[a-z]{4}\d{4}' "$4" ; then
echo Error >&2
exit 1
fi
Are you sure you want to continue if the file doesn't exist? If not, change the condition to
if ! [ -f "$4" ] || grep ...
BTW, you don't really need the PCRE expression here. If you replace \d
by [0-9]
or [[:digit:]]
, you can switch to -E
(extended regular expression).
Answered By - choroba