简体   繁体   中英

How can I use GREP to decide if every line in a file matches my pattern?

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM