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)
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).
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
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
|| 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.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.