Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Grep. Line of text that does not end with "abcd"?

Tags:

regex

grep

sed

Hi I'm looking for a regular expression for: line of text that does not end with a certain word, let's say it's "abcd"
At first I tried with
.*[^abcd]$
That one doesn't work of course. It matches a line that doesn't end with any of the letters a,b,c or d.
So, in Advanced Grep Topics, I found this expression, but couldn't get it to work:
^(?>.*)(?<=abcd)
->
grep -e "^(?>.*)(?<=abcd)$"

Any idea for the expression I need?

like image 641
CCC Avatar asked May 15 '11 02:05

CCC


People also ask

How do you grep for lines that don't match?

To display only the lines that do not match a search pattern, use the -v ( or --invert-match ) option. The -w option tells grep to return only those lines where the specified string is a whole word (enclosed by non-word characters). By default, grep is case-sensitive.

How do you grep with wildcards?

The wildcard * (asterisk) can be a substitute for any number of letters, numbers, or characters. Note that the asterisk (*) works differently in grep. In grep the asterisk only matches multiples of the preceding character. The wildcard * can be a substitute for any number of letters, numbers, or characters.

How do you grep at the end of a line?

Matching the lines that end with a string : The $ regular expression pattern specifies the end of a line. This can be used in grep to match the lines which end with the given string or pattern. 11. -f file option Takes patterns from file, one per line.

What is E flag in grep?

For the following lessons, we'll be making use of grep with a '-E' flag, which enables Extended Regular Expression (ERE) mode for searching regex patterns. On some systems, an aliased command 'egrep' exists.


3 Answers

Have a look at grep's -v option

grep -v 'abcd$'

If you really meant word rather that just "sequence of characters" then use

grep -v '\babcd$'

\b meaning "word-boundary"

like image 60
tobyodavies Avatar answered Oct 27 '22 11:10

tobyodavies


Give this a shot:

grep -v "\<abcd\>$"

Proof of Concept

$ printf "%s\n" "foo abcd bar baz" "foo bar baz abcd" "foo bar bazabcd" | grep -v "\<abcd\>$"
foo abcd bar baz
foo bar bazabcd

Note: This will match whole words as noted by the fact that the 3rd line was returned even though it contained abcd as the last 4 letters

like image 34
SiegeX Avatar answered Oct 27 '22 10:10

SiegeX


grep supports PCRE regular expressions when using -P flag.

One of the reason grep -e "^(?>.*)(?<=abcd)$" does not work is because the lookaround you are using is positive, which means totally opposite of what is required. (?<= is the syntax for positive lookbehind, which tells regex engine to search for lines that ends with abcd.

To search for lines that does not end with certain string, you need to use negative lookbehind. The syntax for negative lookbehind is (?<!. And because negative lookbehind includes exclamation mark which bash will try to interpret as an event, one can not use double quotes to supply regex to grep.

I used following regex to search for the lines that do not end with log.

grep -P '(?<!log)$' < <inputfile>

Similarly you can use above command and replace log with whatever pattern you want to match.

This regex can be used with other programs where inverse matching is not supported, such as -v option of grep

like image 33
traditional Avatar answered Oct 27 '22 12:10

traditional