grep expression for a whole word [duplicate] - regex

This question already has answers here:
How to grep for the whole word
(7 answers)
Closed 6 years ago.
I'm trying to parse the firewall log file and only take the lines that don't contain the router's address as source. The router's address is the obvious 192.168.2.1 and the computer's address is 192.168.2.110.
If I write grep -v 192.168.2.1 then I don't get the destination 192.168.2.110, because it starts with 192.168.2.1. If I don't use anything, then I get the lines from the router, that I would like to filter out. I have searched and tried different regexs, but no matter what I do, I either get both addresses or none.

This force PATTERN to match only whole words grep -w.
grep -v -w 192.168.2.1 file
192.168.2.110
Or Enclose your pattern with \<pattern\>
grep -v '\<192.168.2.1\>' file
192.168.2.110

You can try to use \b which matches with word boundaries:
grep -vP '\b192.168.2.1\b'
or better yet
grep -vP '\b192\.168\.2\.1\b'
You need the -P mode for this to work.

Related

grep utf8/unicode support/ u modifier [duplicate]

This question already has an answer here:
grep -w finds partial match in words with non-latin letters
(1 answer)
Closed 12 months ago.
I'm trying to validate vtt files for a particular format. The regex is functional but UTF8 characters are causing issues. I tried using (?u) with no luck
The regex I'm using is:
grep -P '(?m)^(\d+:\d+[.]\d+\s*-->\s*\d+:\d+[.]\d+|\s*[\w\s]+)|^\s*$' . -r -v
The u flag allows the regex to work as expected here, https://regex101.com/r/21HW2A/1, but I can't find a way to do that in grep. Do I need to swap the \w to all allowed alphanumeric chars or can the u modifier be used in grep somehow?
The \w can be converted to \p{L} which doesn't require the u modifier for unicode support.
Full solution:
grep -P '(?m)^(\d+:\d+[.]\d+\s*-->\s*\d+:\d+[.]\d+|\s*[\p{L}\s]+)|^\s*$' . -r -v

GREP Regex not working properly, but my regex is correct [duplicate]

This question already has answers here:
Extract value from a list of key-value pairs using grep
(3 answers)
Closed 3 years ago.
Hopefully this is a simple mistake I am making, I am fairly new to regex in general. Basically I am trying to extract the name of a website from a text file.
myfile.txt example:
Hello please enjoy your stay at%sbananas.com%sfor the rest of the day. Bye now!
I am trying to extract only the word bananas from this. My regex is as follows:
/(?<=m%s)(.*?)(?=\.com)/
Using regexr online it works just fine but in GREP code I just can't figure out how to get this to work properly. It doesn't return any results. I have tried several variants of the following:
grep "/(?<=m%s)(.*?)(?=\.com)/" myfile.txt
grep -E "/(?<=m%s)(.*?)(?=\.com)/" myfile.txt
grep '/(?<=m%s)(.*?)(?=\.com)/' myfile.txt
grep "(?<=m%s)(.*?)(?=\.com)" myfile.txt
grep '(?<=m%s)(.*?)(?=\.com)' myfile.txt
Nothing seems to work. I would love if someone could point me in the right direction.
The problem with regular expressions in grep and other Unix tools is that they usually support one, two or three different kinds of regular expressions. These are:
Basic regular expressions (BRE)
Extended regular expressions (ERE or EREG)
Perl compatible regular expressions (PCRE or PREG)
Your pattern is in PCRE syntax, therefore you need to identify your pattern as one (using -P). Note that I also removed the m between = and % (I don't know what that was supposed to do).
grep -Po "(?<=%s)(.*?)(?=\.com)" myfile.txt
With -o, you say you only want to print the matching part. My grep man page declares PCRE in grep as experimental so there probably might be cases where you'd get a segmentation fault or where the evaluation takes unusually much time.

Escaping # in BRE regex [duplicate]

This question already has answers here:
Escaping the exclamation point in grep?
(2 answers)
Closed 5 years ago.
I want to find files that are scripts and I need to get from these files the list of all interpreters like Bash, sh, etc.
To find that, I use:
grep "#!/bin/*" ./*
But it displays that:
-bash: !/bin/*": event not found
I assume I need to escape # symbol somehow, but I didn't find that symbol to be escaped in documentation of BRE.
And how I can find files that contain this pattern in regex only on the first line of the file?
the # is no problem, you should escape the !, in Bash it refers to a previous command and must be followed by something, $ for the previous command or a number representing the index of the command in the history. (thx Aaron's correction)
also you may want to change * into .*
like grep "#\!/bin/.*"
If you don't want to escape !, use single quote like:
grep '#!/bin' ....
Also you can disable the regex match by using -F
Could you please try following find command and let me know if this helps.
find -type f -exec grep -l '#!/bin*' {} \+
Escape the ! with \:
grep "#\!/bin/*" ./*

SED: remove pattern from two specific lines [duplicate]

This question already has answers here:
How do I match multiple addresses in sed?
(4 answers)
Closed 7 years ago.
The following command will remove PATTERN from all the lines 13,14,15...29 containing it:
sed -i 13,29s/PATTERN// file
However, I want to remove PATTERN from only the 13th and 29th line. Obviously, I can use
sed -i 13s/PATTERN//;29s/PATTERN// file
but my pattern is long enough to make this inconvenient so I would like to specify the PATTERN only once. Any ideas? I've tried to search for an answer but found nothing.
Also, is there a valid reason why sed uses a comma instead of dash to match a range of lines? I find it illogical.
Thanks in advance.
use awk:
awk 'NR == 13 || NR == 29 { sub(/PATTERN/, "") } { print }' file
of course, you have to use awk compatible re here. https://www.gnu.org/software/gawk/manual/html_node/Regexp.html#Regexp
the first part achieves your requirement, and the second part just print everything out. you can use redirect to put things in another file, and then move over to the original place.
OK, the following is probably the closest thing to what could possibly be the answer to my question:
sed -i '13,29{14,28!s/PATTERN//}' file
A little longer answer with logical-or:
sed -i '13bA;29bA;b;:A;s/PATTERN//' file
Also, using a variable:
VAR=PATTERN
sed -i "13s/$VAR//;29s/$VAR//" file
Thanks to #Jeff Bowman for redirection, and #HuStmpHrrr for the advice to use a variable.

How to use grep to extract a substring? [duplicate]

This question already has answers here:
Closed 10 years ago.
The community reviewed whether to reopen this question 7 months ago and left it closed:
Original close reason(s) were not resolved
Possible Duplicate:
extract regexp result from string and write it to a variable
Here is my command :
grep -E '\*[[:space:]]+FIN[[:space:]]+([^)]+?)') myfile
It outputs :
FIN (SUCCESS)
And I would like it outputs only :
SUCCESS
How can I tell grep to do it ?
You can pipe the output of your grep command to the awk command.
grep -E '*[[:space:]]+FIN[[:space:]]+([^)]+?)') myfile | awk '{print $2}'
I am not sure how to do that with grep alone, as it is not really tailored to that exact use case. Since you are on a platform where grep is, use pipes to your advantage when you can have one command solve part of the problem, and another command the other part.
grep is not capable of outputting a single capture group, but you can use sed to do it instead:
sed 's/\*[[:space:]]\+FIN[[:space:]]\+(\([^)]\+\))/\1/g' file
If you use ack then you can use match groups and the --output switch:
ack '\*\s+FIN\((.+?)\)' --output='$1' myfile