- Grep: how to add an «OR» condition? [duplicate]
- 5 Answers 5
- How to use logical operators (OR, AND & NOT) with Linux grep command
- (1) Use ‘\|’ for using OR in grep
- (2) Use -E option for using OR in grep
- (3) Use -v option for using the NOT operator in grep
- (4) AND operator usage example in grep by using multiple patterns
- (5) AND operator implement using -E option
- Conclusion
- Related
- How can I grep for this or that (2 things) in a file?
- Linux Grep OR, AND, NOT Operator and Logic Examples
- Example Text
- OR Logic
- OR with Extended Grep
- OR with Egrep
- AND Logic
- AND with Multiple Grep
- NOT Logic
- NOT with Multiple Grep Conditions
Grep: how to add an «OR» condition? [duplicate]
How can I introduce a conditional OR into grep? Something like, grepping a file’s type for (JPEG OR JPG), and then sending only those files into the photos folder. For example. I know how to send the file where I want it, and get the file type, I just need some help with the grep part. I’m on OS X, which IMO seems to have modified/customized *nix utilities than what I’m used to in a *nix environment. So hopefully the answers can be as generic/portable as possible.
One might argue that OSX has the more *nix binaries since it is mostly BSD based. I suspect you are far more used the gnu tools.
@Zoredache Uhh .. sure! What you said! I am most familiar with Debian, though I have dabbled with Slackware, CentOS, Gentoo, Ubuntu, and a few others. Debian is my favourite, I almost can’t stand Gentoo and Ubuntu, and Slackware I find to be a bit too unfriendly for me. I tend to break stuff. Great way to learn, though.
You don’t need regexes if you just want to grep for different fixed patterns. Just use the -e parameter for each pattern you want to match, or one -F if you want to supply them as a newline separated list, or -f if you want to read them from a file (see man grep ).
5 Answers 5
You can pass multiple regexes to grep by using the -e option more than once:
grep -e regex1 -e regex2 input_file
will match lines matching regex1 or regex2 .
grep -E «ATTN|MASS|BOND|ANGLE|DIHE|IMPROPER» temp.dat and grep -e ATTN -e MASS -e BOND -e ANGLE -e DIHE -e IMPROPER temp.dat are the same.
I’m also fairly new to regex, but since noone else has answered I’ll give it a shot. The pipe-operator «|» is used for an OR operator.
The following REGEX should get you going somewhere.
(Match anything one or more times followed by either «JPG» or «JPEG» at the end)
Extended answer (editted after learning a bit about (e)grep): Assuming you have a folder with following files in them:
test.jpeg, test.JpEg, test.JPEG, test.jpg, test.JPG, test.notimagefile, test.gif
(Not that creative with names. )
First we start by defining what we know about our pattern: We know that we are looking for the end of the name. Ergo we use the «$» operand to define that each line has to end with the defined pattern. We know that the pattern needs to be either JPEG or JPG. To this we use the pipeline «|» as an or operand. Our pattern is now:
(Match any line ending with EITHER «JPEG» or «JPG»)
However we see that in this example, the only difference is the optional «E». To this we can use the «?» operand (meaning optional). We write:
(Mach any file ending with a pattern like: «J», followed by «P», followed by an optional «E», followed by a «G»).
However we might also like to match files with lowercase letters in file name. To this we introduce the character-class «[. ]». meaning match either of the following. We write:
(Match any file ending with at pattern like: «j» or «J», followed by «p» or «P», followed by an optional «e» or «E», followed by «g» or «G») (This could also be done using the «-i» option in grep, but I took this as an exercise in REGEX)
Finally, since we (hopefully) start to see a pattern, we can omit the unnecessary parentheses. Since there is only one optional letter («E»), we can omit this one. Also, since the file only has this pattern to end on, we can omit the starting and ending parenthesis. Thus we simply get:
Finally; lets assume you also want to find files with «.gif»-filetype, we can add this as a second parameter:
(Here I’ve again added extra parenthesis for readability/grouping. Feel free to remove them if they seem obfuscating.)
Finally, I used ls and a pipeline to send all file names to (e)grep:
test.gif test.JPG test.JpEg test.JPEG test.jpg test.JPG
Second edit: Using the -i option and omitting parenthesis we can shorten it down to only:
How to use logical operators (OR, AND & NOT) with Linux grep command
Linux grep is one of the most used commands by system administrators, computer programmers and ethical hackers. This article will see How to use logical operators (OR, AND, NOT) with Linux grep command. Linux grep command is used to filter information based on pattern matching. Suppose you have logs of the firewall, and you want to search for specific IPs. Linux grep command comes for rescue, and you can use the logical operators’ functionality of this command. Click Here if you are interested in understanding Top Linux Commands for Beginners.
We will use the below data to demonstrate logical AND, OR, and NOT operators in grep:
(1) Use ‘\|’ for using OR in grep
Below commands print lines that match pattern1 or pattern2 till pattern n
(2) Use -E option for using OR in grep
Below commands print lines that match pattern1 or pattern2 till pattern n by using -E option
cat | grep -E '||. '
(3) Use -v option for using the NOT operator in grep
Below commands print lines that not matches pattern1
cat | grep -v ''
(4) AND operator usage example in grep by using multiple patterns
Below commands print lines that matches pattern1, pattern 2 and pattern 3
cat | grep 'pattern1' | grep 'pattern2' | grep 'pattern3'
(5) AND operator implement using -E option
Below commands print lines that match pattern1 and pattern2
Conclusion
Linux grep command is awesome in pattern matching only if you know it very well. In this article, we have covered How to use logical operators (OR, AND & NOT) with Linux grep command.
Related
Subscribe us to receive more such articles updates in your email.
If you have any questions, feel free to ask in the comments section below. Nothing gives me greater joy than helping my readers!
Disclaimer: This tutorial is for educational purpose only. Individual is solely responsible for any illegal act.
How can I grep for this or that (2 things) in a file?
You need to put the expression in quotation marks. The error you are receiving is a result of bash interpretting the ( as a special character.
Also, you need to tell grep to use extended regular expressions.
Without extended regular expressions, you have to escape the | , ( , and ) . Note that we use single quotation marks here. Bash treats backslashes within double quotation marks specially.
The grouping isn’t necessary in this case.
It would be necessary for something like this:
See also grep $’then\nthere’ and grep -e then -e there . Note that \| is not standard in BREs. The rest is. Bash treats backslashes specially within double quotes only before » , $ , \ , ` and newline.
Just a quick addendum, most flavours have a command called egrep which is just grep with -E. I personally like much better to type
egrep "i(Pod|Pad|Phone)" access.log
The stuff documented under REGULAR EXPRESSIONS in the (or at least, my) man page is actually for extended regexps;
grep understands three different versions of regular expression syntax: “basic,” “extended” and “perl.” In GNU grep, there is no difference in available functionality between basic and extended syntaxes. In other implementations, basic regular expressions are less powerful. The following description applies to extended regular expressions; differences for basic regular expressions are summarized afterwards.
But grep does not use them by default — you need the -E switch:
Because (from the man page again):
Since the parentheses are superfluous in this case.
Bash’s elegant simplicity seems to get lost in it’s huge man page.
In addition to the excellent solutions above, I thought I’d try to give you a cheat sheet on how bash parses and interprets statements. Then using this roadmap I’ll parse the examples presented by the questioner to help you better understand why they don’t work as intended.
Note: Shell script lines are used directly. Typed input-lines are first history-expanded.
Each bash line is first tokenized, or in other words chopped into what are called tokens. (Tokenizing occurs before all other expansions, including brace, tilde, parameter, command, arithmetic, process, word splitting, & filename expansion.)
A token here means a portion of the input line separated (delimited) by one of these special meta-characters:
space, - White space. tab, newline, ‘’ ‘&’, - And/Both < | >| >> .or. & ‘;’, - Command termination ‘(’, - Subshell, closed by - ‘)’
Bash uses many other special characters but only these 10 produce the initial tokens.
However because these meta-characters also sometimes must be used within a token, there needs to be a way to take away their special meaning. This is called escaping. Escaping is done either by quoting a string of one or more characters, (i.e. ‘xx..’ , «xx..» ), or by prefixing an individual character with a back-slash, (i.e. \x ). (It’s a little more complicate than this because the quotes also need to be quoted, and because double quotes don’t quote everything, but this simplification will do for now.)
Don’t confuse bash quoting with the idea of quoting a string of text, like in other languages. What is in between quotes in bash are not strings, but rather sections of the input line that have meta-characters escaped so they don’t delimit tokens.
Note, there is an important difference between ‘ , and » , but that’s for another day.
The remaining unescaped meta-characters then become token separators.
For example,
$ echo "x"'y'\g xyg $ echo " <|>$ echo x\; echo y x; echo y
In the first example there are two tokens produced by a space delimiter: echo and xyz .
Likewise in the 2nd example.
In the third example the semicolon is escaped, so there are 4 tokens produced by a space delimiter, echo , x; , echo , and y . The first token is then run as the command, and takes the next three tokens as input. Note the 2nd echo is not executed.
The important thing to remember is that bash first looks for escaping characters ( ‘ , » , and \ ), and then looks for unescaped meta-character delimiters, in that order.
If not escaped then these 10 special characters serve as token delimiters. Some of them also have additional meaning, but first and foremost, they are token delimiters.
What grep expects
In the example above grep needs these tokens, grep , string , filename .
The question’s first try was:
In this case ( , ) and | are unescaped meta characters and so serve to split the input into these tokens: grep , ( , then , | , there , ) , and x.x . grep wants to see grep , then|there , and x.x .
The question’s second try was:
This tokenizes into grep , (then|there) , x.x . You can see this if you swap out grep for echo:
Linux Grep OR, AND, NOT Operator and Logic Examples
lo grep is very useful tool for text search and pattern matching. We have all ready provided tutorial and examples about grep and egrep . In this tutorial we will look grep command or , and , not logic operations in detail.
Example Text
We will use following text during tutorial for grep operations. This is the wage list of Manchester United Football Team.
David de Gea 26 £200,000 2 Years (2019) Sergio Romero 30 £50,000 4 Years (2021) Marcos Rojo 27 £70,000 2 Years (2019) Phil Jones 25 £50,000 2 Years (2019) Chris Smalling 27 £80,000 2 Years (2019) Eric Bailly 23 £75,000 3 Years (2020)
OR Logic
or logic matches all lines if one of the pattern match. We will use \| to specify OR logic. In this example we will look players those age 23 OR 30 .
OR with Extended Grep
Another way to implement OR logic is using grep command extended option with -E . We will specify OR logic with | . In this example we will look players those age 23 OR 30 .
$ grep -E "23|30" manchester.txt
OR with Egrep
Another tool used to implement OR logic is egrep . We will use | operator again. In this example we will look players those age 23 OR 30 .
AND Logic
AND logic will match lines those have all provided patterns. We will use .* for AND operator. In this example we will list players those contract is 2 years and age is 27.
$ grep "27.*2 Years" manchester.txt
AND with Multiple Grep
Another implementation is using multiple grep commands to filter given patterns. In this example we will list players those contract is 2 years and age is 27.
$ grep "2 Years" manchester.txt | grep 27
NOT Logic
NOT logic is used to get results those do not matched given pattern. We will use -v option for grep. In this example we will list players those do not 27 years old.
NOT with Multiple Grep Conditions
We can implement NOT logic multiple times with multiple grep commands. We will pipe multiple grep commands in bash. In this example we will list players those is not 27 years old and not have 2 Years contract.
$ grep -v "27" manchester.txt | grep -v "2 Years"