Reputation: 53
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)
Upvotes: 5
Views: 1240
Reputation: 242403
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).
Upvotes: 6
Reputation: 46
This answer describes how we can use grep
to search for any line not matching a particular regex pattern. We can modify this to provide a one-liner.
grep -Evq "[1-2]" file.txt && echo "error" && exit 1 || true
On the following file.txt
, the error message and exit code will be triggered:
1
2
3
Without || true
, this will always have an false return code. Additionally, this only works for the specified use case; modifying exit 1
to something like true
will break the one-liner.
The regex pattern included within this example should be modified to the desired pattern.
Upvotes: 1
Reputation: 4989
The point about using the exit code of grep
is that it does not match the required condition.
Try the following:
if [ -f "$4" ] ; then
wronglines=$(grep -v pattern "$4")
if [ "$wronglines" = "" ] ; then
echo "all is well"
else
echo "a wrong line in the file"
fi
else
echo "cannot even find the file"
fi
Upvotes: 1