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
Related
I have the following question, a file with pattern like this:
1XYZ00
so the result would be
2XYZ00
I want to change only the first number with another number, for example 9 and not changing anything for the rest of the patern.
I really need to capture this pattern 1XYZ00 and only this one and replace the first number with another one.
I this file I can have numbers but with different pattern and those must not be modified.
The OS is CentOS 7.
Here is what I have tested
sed -E 's/1{1}[A-Z]{3}[0-9]{2}/9{1}[A-Z]{3}[0-9]{2}/g' ~/input.txt > ~/output.txt
I also tried with capture group:
sed --debug -E -r 's/1\(1{1}[A-Z]{3}[0-9]{2}\)/9\1/g' ~/input.txt > ~/output.txt
The sed's debug mode tells me that the pattern matches but no replacement is made.
I think I am pretty close, does any expert could help me please ?
Thanks a lot,
$ cat ip.txt
foo 1XYZ00
xyz 1 2 3
hi 3XYZ00
1XYZ0A
cool 3ABC23
$ # matches any number followed by 3 uppercase and 2 digit characters
$ sed -E 's/[0-9]([A-Z]{3}[0-9]{2})/9\1/' ip.txt
foo 9XYZ00
xyz 1 2 3
hi 9XYZ00
1XYZ0A
cool 9ABC23
$ # matches digit '1' followed by 3 uppercase and 2 digit characters
$ sed -E 's/1([A-Z]{3}[0-9]{2})/9\1/' ip.txt
foo 9XYZ00
xyz 1 2 3
hi 3XYZ00
1XYZ0A
cool 3ABC23
Issue with OP's attempts:
1{1}[A-Z]{3}[0-9]{2} is same as 1[A-Z]{3}[0-9]{2}
Using 9{1}[A-Z]{3}[0-9]{2} in replacement section will give you those characters literally. They don't have any special meaning.
s/1\(1{1}[A-Z]{3}[0-9]{2}\)/9\1/ this one does use capture groups but () shouldn't be escaped with -E option active and 1{1} shouldn't be part of the capture group
I'm not sure if this is enough for you.
sed -i 's/1/9/' input.txt
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
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
Input:
p45-322-16.jpg
Desired output:
p45
I'm trying to make a bash script with grep or awk or sed or something that could run on a bash shell.
Currently I'm stuck with this:
echo "p45-322-16.jpg" | sed 's/\(.*\)-.*/\1/'
Output:
p45-322
You can use cut command: echo "p45-322-16.jpg" | cut -d"-" -f1
You need to limit what you will accept. Right now, you are accepting too much by using ., and the greedy-by-default nature of regexes is consuming too many characters.
Try either limiting the accepted characters to digits only, or specifically excluding the dash:
\([0-9]*\).*
\([^-]*\).*
echo "p45-322-16.jpg" | sed 's/\([^-]*\).*/\1/'
The .* part of your regex is greedy, so it reads as far as possible so that the regex still matches. This means it claims everything up to the last -.
Use [^-]* to match everything until a -.
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).)*$'