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
Related
This question already has answers here:
Non greedy (reluctant) regex matching in sed?
(27 answers)
Closed 2 years ago.
I have this text string within a configuration file:
jdbcService.oraclePool.url=jdbc:oracle:thin:#(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=oracleserver.example.com)(PORT=1521))(CONNECT_DATA=(SERVER=DEDICATED)(SERVICE_NAME=oracleserver55)))
I'd like to replace with sed the value "(HOST=oracleserver.example.com)" without sticking to the text after the = symbol.
I tried to use several regexp but cannot find the working one:
# sed 's/\((HOST=.*?)\)/(HOST=newvalue)/' customer_overrides.properties
jdbcService.oraclePool.url=jdbc:oracle:thin:#(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=oracleserver.example.com)(PORT=1521))(CONNECT_DATA=(SERVER=DEDICATED)(SERVICE_NAME=oracleserver55)))
# sed -E 's/\((HOST=.*?)\)/(HOST=newvalue)/' customer_overrides.properties | grep HOST=
jdbcService.oraclePool.url=jdbc:oracle:thin:#(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=newvalue)
# sed 's/\((HOST=.*[^)])\)/(HOST=newvalue)/' customer_overrides.properties | grep HOST=
jdbcService.oraclePool.url=jdbc:oracle:thin:#(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=newvalue)))
I am working on:
linux RH7
sed-4.2.2-5.el7.x86_64
Thanks for your help!
sed 's/HOST=[^)]*/HOST=foobar/' file
Output:
jdbcService.oraclePool.url=jdbc:oracle:thin:#(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=foobar)(PORT=1521))(CONNECT_DATA=(SERVER=DEDICATED)(SERVICE_NAME=oracleserver55)))
If you don't need to stick to sed this is a good alternative:
perl -pi -e 's/\((HOST=.*?)\)/(HOST=foobar)/g' customer_overrides.properties
But I prefer Cyrus' reply :)
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
This question already has answers here:
How to use sed/grep to extract text between two words?
(14 answers)
Closed 2 years ago.
I have very strange interest to pattern match a line for a string and extract a value using grep. Below is the input and I want to extract the date alone from the string.
Input Host-GOOGLE-production.2015-08-01-21.migrant.deploy:{R:[{A:"0b87654nuy",RC:"JAVA".....[and the line continues]
For the above input, I wanted to write a regex that matches the date and string that comes after {A:" and before ",RC:. I know I can do this through sed and awk but I wanted to perform this task only through grep.
As a first step, to extract only the data, I tried the below command but it dint work.
Someone know how to extract both these strings to extract the values. please share your thoughts. It would be nice if I get an answers/suggestion that extract both values 2015-08-01 & 0b87654nuy in one single command using grep
$grep -o --perl-regexp "(Host-GOOGLE-production.([0-9]+?-[0-9]+?-[0-9]+)?-.*)"
Desired O/P for the above command: 2015-08-01
I wanted to write a regex that matches the date and string that comes after {A:" and before ",RC:
You can use this grep:
grep -oP '(?<=A:").*?(?=",RC:)' file
0b87654nuy
It would be nice if I get an answers/suggestion that extract both values 2015-08-01 & 0b87654nuy in one single command using grep
Use \K and alternation operator to get both outputs.
grep -oP '\bHost-GOOGLE-production\.\K[0-9]+-[0-9]+-[0-9]+(?=-)|A:"\K.[^"]*(?=",RC:)'
Example:
$ echo 'Host-GOOGLE-production.2015-08-01-21.migrant.deploy:{R:[{A:"0b87654nuy",RC:"JAVA".....[and the line continues]' | grep -oP '\bHost-GOOGLE-production\.\K[0-9]+-[0-9]+-[0-9]+(?=-)|A:"\K.[^"]*(?=",RC:)'
2015-08-01
0b87654nuy
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).)*$'
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