How to use negative regex matching with grep -E? [duplicate] - regex

This question already has answers here:
Negative matching using grep (match lines that do not contain foo)
(3 answers)
Closed 8 years ago.
I'm using the following regex via grep -E to match a specific string of chars via | pipe.
$ git log <more switches here> | grep -E "match me"
Output:
match me once
match me twice
What I'm really looking for a is a negative match (return all output lines that don't contain the specified string something like the following but grep doesn't like it:
$ git log <more switches here> | grep -E "^match me"
desired output:
whatever 1
whatever 2
here is the full output that comes back from the command line:
match me once
match me twice
whatever 1
whatever 2
How to do arrive at the desired output per a negative regex match?

Use the -v option which inverts the matches, selecting non-matching lines
grep -v 'match me'
Another option is to use -P which interprets the pattern as a Perl regular expression.
grep -P '^((?!match me).)*$'

Related

Extract word and digit from string using SED [duplicate]

This question already has answers here:
sed: print only matching group
(5 answers)
Closed 2 years ago.
how can I extract the TIC-9890 from a
branch name that looks like feature/TIC-9890/some-other-wording
I am not a SED expert, but I managed to come up with:
echo "feature/TIC-000/random-description" |
sed -n 's/.*\(TIC-[0-9]\{1,\}\).*/\1/'
This seems to work fine if the TIC-\d+ string is in there,
but returns the entire string if that is missing...
However, I need it to return null or empty string if the match isn't present.
You should add a p option to print and it should fly then. Why because we have stopped printing of sed by using -n option so when substitution happens then p needs to be used to print it.
echo "feature/TIC-000/random-description" | sed -n 's/.*\(TIC-[0-9]\{1,\}\).*/\1/p'
From man sed page:
-n, --quiet, --silent suppress automatic printing of pattern space
p Print the current pattern space.
OR as per #anubhava sir's comments one could use grep with -E option we could try:
echo "feature/TIC-000/random-description" | grep -oE 'TIC-[0-9]+'

Regex works but not with egrep in bash on Windows [duplicate]

This question already has answers here:
regex - matching non-necessarily consecutive occurrences
(4 answers)
Closed 3 years ago.
I have a text file test.txt with the following content:
20001
200134
20103040
203004038002
I want to use the following egrep command to show the matches:
egrep '^(?!(?:.*?0){6,})(?=(?:.*?0){3,})[0-9]+$' test.txt
However for some reason egrep doesn't output anything. But I can see that my regex does work on regex101 link:
https://regex101.com/r/XZDonL/1
Am I using egrep wrong? Because I don't know what I'm doing wrong. By the way I'm using bash on Windows.
The lookaround notation (?! is not supported in egrep but you might try grep -P if supported to make it perl compatible.
It is seems you want to match numbers which contain 3 - 5 times a zero.
Another option to match this is to match 0+ times a digit [1-9] with 3 times a zero and 2 times an optional zero.
You might use this pattern with egrep:
^[1-9]*0[1-9]*0[1-9]*0[1-9]*0?[1-9]*0?[1-9]*$
regex demo
For example:
egrep '^[1-9]*0[1-9]*0[1-9]*0[1-9]*0?[1-9]*0?[1-9]*$' test.txt

Print specific string in a line after matched word in bash [duplicate]

This question already has answers here:
How to extract string following a pattern with grep, regex or perl [duplicate]
(8 answers)
Closed 4 years ago.
Situation
There is a file called test that consists on the following text:
this is the first line
version=1.2.3.4
this is the third line
How can i print via bash only:
1.2.3.4
Note: I want always to print until end of line what is after "version=" not searching for 1.2.3.4
Thank you
Using GNU grep :
grep -Po '^version=\K.*'
-P enables PCRE regex, -o is used to only display what is matched rather than whole lines and the \K meta-character specifies not to display what precedes.
Using sed :
sed -n 's/^version=\(.*\)/\1/p'
-n disables auto-printing, then the substitution command will replace the "version=[...]" line by only its end through a capturing group. The substitution is only effective on the second line, which trigger the p instruction to print the (transformed) line.
you can use:
grep version file | cut -d\= -f2

Exclude pattern in a Grep using extended regex [duplicate]

This question already has answers here:
How to invert a grep expression
(5 answers)
Regular expression to match a line that doesn't contain a word
(34 answers)
Closed 5 years ago.
I got a Grep that is killing me
Let's suppose i got the a file (file.xml) with the two below entries:
pos_ADF_datasource-1450-jdbc.xml
datasource-1450-jdbc.xml
Now If i run the below grep:
grep -E '(ADF)' file.txt
I got the below output:
pos_ADF_datasource-1450-jdbc.xml
Now i want to exclude ADF to get the other entry, it should be easy, but i tried it all and I'm unable to let it works:
grep -E '(?<!ADF)' file.txt
I tried many but i'm sure there is something i'm not considering that is making my expression not working...
I need and want to use the -E, i know it works not using the extended regex!
Please guys me light me!
RESOLVED:
Thanks Wiktor for the below consideration:
ERE POSIX does not support lookarounds. Even if you use -P excluding 'ADF' it will just match any position that is not preceded with ADF
You cannot check with an ERE regex if a string does not contain a pattern. Only if it is not equal, does not start/end with a pattern. You may only do it with a PCRE regex. grep -P '^(?!.*ADF)' file.txt
Then i figured it out with grep -Pe:
grep -Pe "^((?!.*ADF).)*-jdbc.xml$" file.xml

regex: find strings that do not begin with a certain prefix [duplicate]

This question already has an answer here:
Regular expression for a string that does not start with a sequence
(1 answer)
Closed 9 years ago.
I want to find a word in strings, but only if it doesn't begin with a prefix.
for example.
I'd like to find all the appearances of APP_PERFORM_TASK, but only if they are not starting with a prefix of CMD_DO("
so,
CMD_DO("APP_PERFORM_TASK") <- OK (i don't need to know about this)
BLAH("APP_PERFORM_TASK") <-- NOT OK, this should match my search.
I tried:
(?!CMD_DO\(")APP_PERFORM_TASK
But that doesn't produce the results I need. What I doing wrong?
Here's a quick way:
Use the --invert-match (also known as -v) flag to ignore CMD_DO and pipe the results to a second grep that only matches BLAH:
grep -v CMD_DO dummy | grep BLAH
Try replacing NegativeLookAhead (?!) with NegativeLookBehind (?<!) in your regex
(?<!CMD_DO\(")APP_PERFORM_TASK
Check this in action here
Based on your comment: Let's concentrate on command line tool grep
Here is grep solution without using -P switch (perl like regex):
grep 'APP_PERFORM_TASK' file | grep -v '^CMD_DO("'
Here is grep solution using -P switch and negative lokbehind:
grep -P '(?<!^CMD_DO\(")APP_PERFORM_TASK' file
Try this
(?!CMD_DO\(").*APP_PERFORM_TASK.*
To handle an input line with both the desirable and undesirable forms like:
CMD_DO("APP_PERFORM_TASK") BLAH("APP_PERFORM_TASK")
you'd need something like this in awk (using GNU awk for gensub()):
awk -v s="APP_PERFORM_TASK" 'gensub("CMD_DO\\(\\""s,"","") ~ s' file
i.e. get rid of all of the unwanted occurrences of the string then test whats left.
An awk version
awk '/APP_PERFORM_TASK/ && !/^CMD_DO/' file