How to run grep with multiple AND patterns?
I would like to get the multi pattern match with implicit AND between patterns, i.e. equivalent to running several greps in a sequence:
grep pattern1 | grep pattern2 | ...
So how to convert it to something like?
grep pattern1 & pattern2 & pattern3
I would like to use single grep because I am building arguments dynamically, so everything has to fit in one string. Using filter is system feature, not grep, so it is not an argument for it.
Don't confuse this question with:
grep "pattern1|pattern2|..."
This is an OR multi pattern match.
grep regular-expression
add a comment |
I would like to get the multi pattern match with implicit AND between patterns, i.e. equivalent to running several greps in a sequence:
grep pattern1 | grep pattern2 | ...
So how to convert it to something like?
grep pattern1 & pattern2 & pattern3
I would like to use single grep because I am building arguments dynamically, so everything has to fit in one string. Using filter is system feature, not grep, so it is not an argument for it.
Don't confuse this question with:
grep "pattern1|pattern2|..."
This is an OR multi pattern match.
grep regular-expression
Similar: Match all patterns from file at once
– kenorb
Dec 22 '16 at 15:26
Similar question on SO: Check if multiple strings or regexes exist in a file
– codeforester
Apr 13 '18 at 17:47
add a comment |
I would like to get the multi pattern match with implicit AND between patterns, i.e. equivalent to running several greps in a sequence:
grep pattern1 | grep pattern2 | ...
So how to convert it to something like?
grep pattern1 & pattern2 & pattern3
I would like to use single grep because I am building arguments dynamically, so everything has to fit in one string. Using filter is system feature, not grep, so it is not an argument for it.
Don't confuse this question with:
grep "pattern1|pattern2|..."
This is an OR multi pattern match.
grep regular-expression
I would like to get the multi pattern match with implicit AND between patterns, i.e. equivalent to running several greps in a sequence:
grep pattern1 | grep pattern2 | ...
So how to convert it to something like?
grep pattern1 & pattern2 & pattern3
I would like to use single grep because I am building arguments dynamically, so everything has to fit in one string. Using filter is system feature, not grep, so it is not an argument for it.
Don't confuse this question with:
grep "pattern1|pattern2|..."
This is an OR multi pattern match.
grep regular-expression
grep regular-expression
edited Nov 13 '12 at 21:01
dubiousjim
1,9981223
1,9981223
asked Nov 10 '12 at 7:45
greenoldmangreenoldman
2,492104259
2,492104259
Similar: Match all patterns from file at once
– kenorb
Dec 22 '16 at 15:26
Similar question on SO: Check if multiple strings or regexes exist in a file
– codeforester
Apr 13 '18 at 17:47
add a comment |
Similar: Match all patterns from file at once
– kenorb
Dec 22 '16 at 15:26
Similar question on SO: Check if multiple strings or regexes exist in a file
– codeforester
Apr 13 '18 at 17:47
Similar: Match all patterns from file at once
– kenorb
Dec 22 '16 at 15:26
Similar: Match all patterns from file at once
– kenorb
Dec 22 '16 at 15:26
Similar question on SO: Check if multiple strings or regexes exist in a file
– codeforester
Apr 13 '18 at 17:47
Similar question on SO: Check if multiple strings or regexes exist in a file
– codeforester
Apr 13 '18 at 17:47
add a comment |
9 Answers
9
active
oldest
votes
agrep can do it with this syntax:
agrep 'pattern1;pattern2'
With GNU grep, when built with PCRE support, you can do:
grep -P '^(?=.*pattern1)(?=.*pattern2)'
With ast grep:
grep -X '.*pattern1.*&.*pattern2.*'
(adding .*s as <x>&<y> matches strings that match both <x> and <y> exactly, a&b would never match as there's no such string that can be both a and b at the same time).
If the patterns don't overlap, you may also be able to do:
grep -e 'pattern1.*pattern2' -e 'pattern2.*pattern1'
The best portable way is probably with awk as already mentioned:
awk '/pattern1/ && /pattern2/'
With sed:
sed -e '/pattern1/!d' -e '/pattern2/!d'
Please beware that all those will have different regular expression syntax.
1
Theagrepsyntax is not working for me... which version was it introduced in?
– Raman
Sep 5 '16 at 22:15
@Raman 2.04 from 1992 already had it. I've no reason to believe it wasn't there from the start. Newer (after 1992) versions ofagrepcan be found included with glimpse/webglimpse. Possibly you have a different implementation. I had a mistake for the ast-grep version though, the option for augmented regexps is-X, not-A.
– Stéphane Chazelas
Sep 6 '16 at 5:55
@StéphaneChazelas Thanks, I haveagrep0.8.0 on Fedora 23. This appears to be a differentagrepthan the one you reference.
– Raman
Sep 6 '16 at 6:37
1
@Raman, yours sounds like TREagrep.
– Stéphane Chazelas
Sep 6 '16 at 7:01
1
@Techiee, or justawk '/p1/ && /p2/ {n++}; END {print 0+n}'
– Stéphane Chazelas
Jun 28 '17 at 20:23
|
show 5 more comments
You didn't specify grep version, this is important. Some regexp engines allow multiple matching groupped by AND using '&' but this is non-standard and non-portable feature. But, at least GNU grep doesn't support this.
OTOH you can simply replace grep with sed, awk, perl, etc. (listed in order of weight increasing). With awk, the command would look like
awk '/regexp1/ && /regexp2/ && /regexp3/ { print; }'
and it can be constructed to be specified in command line in easy way.
3
Just remember thatawkuses ERE's, e.g. the equivalent ofgrep -E, as opposed to the BRE's that plaingrepuses.
– jw013
Nov 10 '12 at 9:42
3
awk's regexes are called EREs, but in fact they're a bit idiosyncratic. Here are probably more details than anyone cares for: wiki.alpinelinux.org/wiki/Regex
– dubiousjim
Nov 10 '12 at 15:35
Thank you, grep 2.7.3 (openSUSE). I upvoted you, but I will keep question open for a while, maybe there is some trick for grep (not that I dislikeawk-- simply knowing more is better).
– greenoldman
Nov 10 '12 at 15:42
1
The default action is to print the matching line so the{ print; }part isn't really necessary or useful here.
– tripleee
Apr 20 '17 at 11:58
add a comment |
This is not a very good solution but illustrates a somewhat cool "trick"
function chained-grep() {
local pattern="$1"
if [[ -z "$pattern" ]]; then
cat
return
fi
shift
grep -- "$pattern" | chained-grep "$@"
}
cat something | chained-grep all patterns must match order but matter dont
Use eitherchained-grep()orfunction chained-grepbut notfunction chained-grep(): unix.stackexchange.com/questions/73750/…
– nisetama
8 hours ago
add a comment |
If patterns contains one pattern per line, you can do something like this:
awk 'NR==FNR{a[$0];next}{for(i in a)if($0!~i)next}1' patterns -
Or this matches substrings instead of regular expressions:
awk 'NR==FNR{a[$0];next}{for(i in a)if(!index($0,i))next}1' patterns -
To print all instead of no lines of the input in the case that patterns is empty, replace NR==FNR with FILENAME==ARGV[1], or with ARGIND==1 in gawk.
These functions print the lines of STDIN which contain each string specified as an argument as a substring. ga stands for grep all and gai ignores case.
ga(){ awk 'FILENAME==ARGV[1]{a[$0];next}{for(i in a)if(!index($0,i))next}1' <(printf %s\n "$@") -; }
gai(){ awk 'FILENAME==ARGV[1]{a[tolower($0)];next}{for(i in a)if(!index(tolower($0),i))next}1' <(printf %s\n "$@") -; }
add a comment |
git grep
Here is the syntax using git grep combining multiple patterns using Boolean expressions:
git grep -e pattern1 --and -e pattern2 --and -e pattern3
The above command will print lines matching all the patterns at once.
If the files aren't under version control, add --no-index param.
Search files in the current directory that is not managed by Git.
Check man git-grep for help.
See also: Check if all of multiple strings or regexes exist in a file.
add a comment |
This shell command may help:
eval "</dev/stdin $(printf "|grep '%s'" pattern1 pattern2)" FILE
However it's easier if all your patterns are stored in the file, so you can define the following alias:
alias grep-all="cat $(xargs printf '| grep "%s"' < patterns.txt)"
and use it as:
cat text.txt | grep-all
You can of course modify the alias depending on your required syntax, so with this alias:
alias grep-all="</dev/stdin $(xargs printf '|grep "%s"' < patterns.txt)"
you can use just a single command, e.g.
grep-all text.txt
For more ideas, check also: Match all patterns from file at once.
For AND operation per file, see: Check if all of multiple strings or regexes exist in a file.
Your first command seems to search only for the last pattern. It’s not clear what you are trying to accomplish with</dev/stdin. I couldn’t get your second command to work at all without changing it.
– G-Man
Aug 17 '18 at 15:02
add a comment |
ripgrep
Here is the example using rg:
rg -N '(?P<p1>.*pattern1.*)(?P<p2>.*pattern2.*)(?P<p3>.*pattern3.*)' file.txt
It's one of the quickest grepping tools, since it's built on top of Rust's regex engine which uses finite automata, SIMD and aggressive literal optimizations to make searching very fast.
See also related feature request at GH-875.
add a comment |
Here's my take, and this works for words in multiple lines:
Use find . -type f followed by as many -exec grep -q 'first_word' {} ;
and the last keyword with -exec grep -l 'nth_word' {} ;
-q quiet / silent -l show files with matches
The following returns list of filenames with words 'rabbit' and 'hole' in them: find . -type f -exec grep -q 'rabbit' {} ; -exec grep -l 'hole' {} ;
New contributor
StackRover is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.
add a comment |
To find ALL of the words (or patterns), you can run grep in FOR loop.
The main advantage here, is searching from a list of regexs.
EDIT my answer with a real example:
# search_all_regex_and_error_if_missing.sh
find_list="
^a+$
^b+$
^h+$
^d+$
"
for item in $find_list; do
if grep -E "$item" file_to_search_within.txt
then
echo "$item found in file."
else
echo "Error: $item not found in file. Exiting!"
exit 1
fi
done
Now let's run it on this file:
hhhhhhhhhh
aaaaaaa
bbbbbbbbb
ababbabaabbaaa
ccccccc
dsfsdf
bbbb
cccdd
aa
caa
# ./search_all_regex_and_error_if_missing.sh
aaaaaaa aa
^a+$ found in file.
bbbbbbbbb bbbb
^b+$ found in file.
hhhhhhhhhh
^h+$ found in file.
Error: ^d+$ not found in file. Exiting!
1
Your logic is faulty -- I asked forALLoperator, your code works asORoperator, notAND. And btw. for that (OR) is much easier solution given right in the question.
– greenoldman
Aug 14 '18 at 22:18
@greenoldman The logic is simple: The for will loop on ALL of the words/patterns in the list, and if it is found in file - will print it. So just remove the else if you don't need action in case word was not found.
– Noam Manos
Aug 16 '18 at 15:07
I understand your logic as well as my question -- I was asking aboutANDoperator, meaning the file is only a positive hit if it matches pattern A and pattern B and pattern C and...ANDIn you case file is positive hit if it matches pattern A or pattern B or... Do you see the difference now?
– greenoldman
Aug 17 '18 at 6:19
@greenoldman not sure why you think this loop does not check AND condition for all patterns? So I've edited my answer with a real example: It will search in file for all regex of list, and on the first one which is missing - will exit with error.
– Noam Manos
Aug 19 '18 at 15:04
You have it right in front of your eyes, you have positive match just after first match is executed. You should have "collect" all outcomes and computeANDon them. Then you should rewrite the script to run on multiple files -- then maybe you realize that the question is already answered and your attempt does not bring anything to the table, sorry.
– greenoldman
Aug 20 '18 at 5:56
|
show 3 more comments
Your Answer
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "106"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: false,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: null,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f55359%2fhow-to-run-grep-with-multiple-and-patterns%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
9 Answers
9
active
oldest
votes
9 Answers
9
active
oldest
votes
active
oldest
votes
active
oldest
votes
agrep can do it with this syntax:
agrep 'pattern1;pattern2'
With GNU grep, when built with PCRE support, you can do:
grep -P '^(?=.*pattern1)(?=.*pattern2)'
With ast grep:
grep -X '.*pattern1.*&.*pattern2.*'
(adding .*s as <x>&<y> matches strings that match both <x> and <y> exactly, a&b would never match as there's no such string that can be both a and b at the same time).
If the patterns don't overlap, you may also be able to do:
grep -e 'pattern1.*pattern2' -e 'pattern2.*pattern1'
The best portable way is probably with awk as already mentioned:
awk '/pattern1/ && /pattern2/'
With sed:
sed -e '/pattern1/!d' -e '/pattern2/!d'
Please beware that all those will have different regular expression syntax.
1
Theagrepsyntax is not working for me... which version was it introduced in?
– Raman
Sep 5 '16 at 22:15
@Raman 2.04 from 1992 already had it. I've no reason to believe it wasn't there from the start. Newer (after 1992) versions ofagrepcan be found included with glimpse/webglimpse. Possibly you have a different implementation. I had a mistake for the ast-grep version though, the option for augmented regexps is-X, not-A.
– Stéphane Chazelas
Sep 6 '16 at 5:55
@StéphaneChazelas Thanks, I haveagrep0.8.0 on Fedora 23. This appears to be a differentagrepthan the one you reference.
– Raman
Sep 6 '16 at 6:37
1
@Raman, yours sounds like TREagrep.
– Stéphane Chazelas
Sep 6 '16 at 7:01
1
@Techiee, or justawk '/p1/ && /p2/ {n++}; END {print 0+n}'
– Stéphane Chazelas
Jun 28 '17 at 20:23
|
show 5 more comments
agrep can do it with this syntax:
agrep 'pattern1;pattern2'
With GNU grep, when built with PCRE support, you can do:
grep -P '^(?=.*pattern1)(?=.*pattern2)'
With ast grep:
grep -X '.*pattern1.*&.*pattern2.*'
(adding .*s as <x>&<y> matches strings that match both <x> and <y> exactly, a&b would never match as there's no such string that can be both a and b at the same time).
If the patterns don't overlap, you may also be able to do:
grep -e 'pattern1.*pattern2' -e 'pattern2.*pattern1'
The best portable way is probably with awk as already mentioned:
awk '/pattern1/ && /pattern2/'
With sed:
sed -e '/pattern1/!d' -e '/pattern2/!d'
Please beware that all those will have different regular expression syntax.
1
Theagrepsyntax is not working for me... which version was it introduced in?
– Raman
Sep 5 '16 at 22:15
@Raman 2.04 from 1992 already had it. I've no reason to believe it wasn't there from the start. Newer (after 1992) versions ofagrepcan be found included with glimpse/webglimpse. Possibly you have a different implementation. I had a mistake for the ast-grep version though, the option for augmented regexps is-X, not-A.
– Stéphane Chazelas
Sep 6 '16 at 5:55
@StéphaneChazelas Thanks, I haveagrep0.8.0 on Fedora 23. This appears to be a differentagrepthan the one you reference.
– Raman
Sep 6 '16 at 6:37
1
@Raman, yours sounds like TREagrep.
– Stéphane Chazelas
Sep 6 '16 at 7:01
1
@Techiee, or justawk '/p1/ && /p2/ {n++}; END {print 0+n}'
– Stéphane Chazelas
Jun 28 '17 at 20:23
|
show 5 more comments
agrep can do it with this syntax:
agrep 'pattern1;pattern2'
With GNU grep, when built with PCRE support, you can do:
grep -P '^(?=.*pattern1)(?=.*pattern2)'
With ast grep:
grep -X '.*pattern1.*&.*pattern2.*'
(adding .*s as <x>&<y> matches strings that match both <x> and <y> exactly, a&b would never match as there's no such string that can be both a and b at the same time).
If the patterns don't overlap, you may also be able to do:
grep -e 'pattern1.*pattern2' -e 'pattern2.*pattern1'
The best portable way is probably with awk as already mentioned:
awk '/pattern1/ && /pattern2/'
With sed:
sed -e '/pattern1/!d' -e '/pattern2/!d'
Please beware that all those will have different regular expression syntax.
agrep can do it with this syntax:
agrep 'pattern1;pattern2'
With GNU grep, when built with PCRE support, you can do:
grep -P '^(?=.*pattern1)(?=.*pattern2)'
With ast grep:
grep -X '.*pattern1.*&.*pattern2.*'
(adding .*s as <x>&<y> matches strings that match both <x> and <y> exactly, a&b would never match as there's no such string that can be both a and b at the same time).
If the patterns don't overlap, you may also be able to do:
grep -e 'pattern1.*pattern2' -e 'pattern2.*pattern1'
The best portable way is probably with awk as already mentioned:
awk '/pattern1/ && /pattern2/'
With sed:
sed -e '/pattern1/!d' -e '/pattern2/!d'
Please beware that all those will have different regular expression syntax.
edited Sep 6 '16 at 5:55
answered Nov 10 '12 at 20:13
Stéphane ChazelasStéphane Chazelas
301k55565917
301k55565917
1
Theagrepsyntax is not working for me... which version was it introduced in?
– Raman
Sep 5 '16 at 22:15
@Raman 2.04 from 1992 already had it. I've no reason to believe it wasn't there from the start. Newer (after 1992) versions ofagrepcan be found included with glimpse/webglimpse. Possibly you have a different implementation. I had a mistake for the ast-grep version though, the option for augmented regexps is-X, not-A.
– Stéphane Chazelas
Sep 6 '16 at 5:55
@StéphaneChazelas Thanks, I haveagrep0.8.0 on Fedora 23. This appears to be a differentagrepthan the one you reference.
– Raman
Sep 6 '16 at 6:37
1
@Raman, yours sounds like TREagrep.
– Stéphane Chazelas
Sep 6 '16 at 7:01
1
@Techiee, or justawk '/p1/ && /p2/ {n++}; END {print 0+n}'
– Stéphane Chazelas
Jun 28 '17 at 20:23
|
show 5 more comments
1
Theagrepsyntax is not working for me... which version was it introduced in?
– Raman
Sep 5 '16 at 22:15
@Raman 2.04 from 1992 already had it. I've no reason to believe it wasn't there from the start. Newer (after 1992) versions ofagrepcan be found included with glimpse/webglimpse. Possibly you have a different implementation. I had a mistake for the ast-grep version though, the option for augmented regexps is-X, not-A.
– Stéphane Chazelas
Sep 6 '16 at 5:55
@StéphaneChazelas Thanks, I haveagrep0.8.0 on Fedora 23. This appears to be a differentagrepthan the one you reference.
– Raman
Sep 6 '16 at 6:37
1
@Raman, yours sounds like TREagrep.
– Stéphane Chazelas
Sep 6 '16 at 7:01
1
@Techiee, or justawk '/p1/ && /p2/ {n++}; END {print 0+n}'
– Stéphane Chazelas
Jun 28 '17 at 20:23
1
1
The
agrep syntax is not working for me... which version was it introduced in?– Raman
Sep 5 '16 at 22:15
The
agrep syntax is not working for me... which version was it introduced in?– Raman
Sep 5 '16 at 22:15
@Raman 2.04 from 1992 already had it. I've no reason to believe it wasn't there from the start. Newer (after 1992) versions of
agrep can be found included with glimpse/webglimpse. Possibly you have a different implementation. I had a mistake for the ast-grep version though, the option for augmented regexps is -X, not -A.– Stéphane Chazelas
Sep 6 '16 at 5:55
@Raman 2.04 from 1992 already had it. I've no reason to believe it wasn't there from the start. Newer (after 1992) versions of
agrep can be found included with glimpse/webglimpse. Possibly you have a different implementation. I had a mistake for the ast-grep version though, the option for augmented regexps is -X, not -A.– Stéphane Chazelas
Sep 6 '16 at 5:55
@StéphaneChazelas Thanks, I have
agrep 0.8.0 on Fedora 23. This appears to be a different agrep than the one you reference.– Raman
Sep 6 '16 at 6:37
@StéphaneChazelas Thanks, I have
agrep 0.8.0 on Fedora 23. This appears to be a different agrep than the one you reference.– Raman
Sep 6 '16 at 6:37
1
1
@Raman, yours sounds like TRE
agrep.– Stéphane Chazelas
Sep 6 '16 at 7:01
@Raman, yours sounds like TRE
agrep.– Stéphane Chazelas
Sep 6 '16 at 7:01
1
1
@Techiee, or just
awk '/p1/ && /p2/ {n++}; END {print 0+n}'– Stéphane Chazelas
Jun 28 '17 at 20:23
@Techiee, or just
awk '/p1/ && /p2/ {n++}; END {print 0+n}'– Stéphane Chazelas
Jun 28 '17 at 20:23
|
show 5 more comments
You didn't specify grep version, this is important. Some regexp engines allow multiple matching groupped by AND using '&' but this is non-standard and non-portable feature. But, at least GNU grep doesn't support this.
OTOH you can simply replace grep with sed, awk, perl, etc. (listed in order of weight increasing). With awk, the command would look like
awk '/regexp1/ && /regexp2/ && /regexp3/ { print; }'
and it can be constructed to be specified in command line in easy way.
3
Just remember thatawkuses ERE's, e.g. the equivalent ofgrep -E, as opposed to the BRE's that plaingrepuses.
– jw013
Nov 10 '12 at 9:42
3
awk's regexes are called EREs, but in fact they're a bit idiosyncratic. Here are probably more details than anyone cares for: wiki.alpinelinux.org/wiki/Regex
– dubiousjim
Nov 10 '12 at 15:35
Thank you, grep 2.7.3 (openSUSE). I upvoted you, but I will keep question open for a while, maybe there is some trick for grep (not that I dislikeawk-- simply knowing more is better).
– greenoldman
Nov 10 '12 at 15:42
1
The default action is to print the matching line so the{ print; }part isn't really necessary or useful here.
– tripleee
Apr 20 '17 at 11:58
add a comment |
You didn't specify grep version, this is important. Some regexp engines allow multiple matching groupped by AND using '&' but this is non-standard and non-portable feature. But, at least GNU grep doesn't support this.
OTOH you can simply replace grep with sed, awk, perl, etc. (listed in order of weight increasing). With awk, the command would look like
awk '/regexp1/ && /regexp2/ && /regexp3/ { print; }'
and it can be constructed to be specified in command line in easy way.
3
Just remember thatawkuses ERE's, e.g. the equivalent ofgrep -E, as opposed to the BRE's that plaingrepuses.
– jw013
Nov 10 '12 at 9:42
3
awk's regexes are called EREs, but in fact they're a bit idiosyncratic. Here are probably more details than anyone cares for: wiki.alpinelinux.org/wiki/Regex
– dubiousjim
Nov 10 '12 at 15:35
Thank you, grep 2.7.3 (openSUSE). I upvoted you, but I will keep question open for a while, maybe there is some trick for grep (not that I dislikeawk-- simply knowing more is better).
– greenoldman
Nov 10 '12 at 15:42
1
The default action is to print the matching line so the{ print; }part isn't really necessary or useful here.
– tripleee
Apr 20 '17 at 11:58
add a comment |
You didn't specify grep version, this is important. Some regexp engines allow multiple matching groupped by AND using '&' but this is non-standard and non-portable feature. But, at least GNU grep doesn't support this.
OTOH you can simply replace grep with sed, awk, perl, etc. (listed in order of weight increasing). With awk, the command would look like
awk '/regexp1/ && /regexp2/ && /regexp3/ { print; }'
and it can be constructed to be specified in command line in easy way.
You didn't specify grep version, this is important. Some regexp engines allow multiple matching groupped by AND using '&' but this is non-standard and non-portable feature. But, at least GNU grep doesn't support this.
OTOH you can simply replace grep with sed, awk, perl, etc. (listed in order of weight increasing). With awk, the command would look like
awk '/regexp1/ && /regexp2/ && /regexp3/ { print; }'
and it can be constructed to be specified in command line in easy way.
answered Nov 10 '12 at 8:34
NetchNetch
1,862910
1,862910
3
Just remember thatawkuses ERE's, e.g. the equivalent ofgrep -E, as opposed to the BRE's that plaingrepuses.
– jw013
Nov 10 '12 at 9:42
3
awk's regexes are called EREs, but in fact they're a bit idiosyncratic. Here are probably more details than anyone cares for: wiki.alpinelinux.org/wiki/Regex
– dubiousjim
Nov 10 '12 at 15:35
Thank you, grep 2.7.3 (openSUSE). I upvoted you, but I will keep question open for a while, maybe there is some trick for grep (not that I dislikeawk-- simply knowing more is better).
– greenoldman
Nov 10 '12 at 15:42
1
The default action is to print the matching line so the{ print; }part isn't really necessary or useful here.
– tripleee
Apr 20 '17 at 11:58
add a comment |
3
Just remember thatawkuses ERE's, e.g. the equivalent ofgrep -E, as opposed to the BRE's that plaingrepuses.
– jw013
Nov 10 '12 at 9:42
3
awk's regexes are called EREs, but in fact they're a bit idiosyncratic. Here are probably more details than anyone cares for: wiki.alpinelinux.org/wiki/Regex
– dubiousjim
Nov 10 '12 at 15:35
Thank you, grep 2.7.3 (openSUSE). I upvoted you, but I will keep question open for a while, maybe there is some trick for grep (not that I dislikeawk-- simply knowing more is better).
– greenoldman
Nov 10 '12 at 15:42
1
The default action is to print the matching line so the{ print; }part isn't really necessary or useful here.
– tripleee
Apr 20 '17 at 11:58
3
3
Just remember that
awk uses ERE's, e.g. the equivalent of grep -E, as opposed to the BRE's that plain grep uses.– jw013
Nov 10 '12 at 9:42
Just remember that
awk uses ERE's, e.g. the equivalent of grep -E, as opposed to the BRE's that plain grep uses.– jw013
Nov 10 '12 at 9:42
3
3
awk's regexes are called EREs, but in fact they're a bit idiosyncratic. Here are probably more details than anyone cares for: wiki.alpinelinux.org/wiki/Regex– dubiousjim
Nov 10 '12 at 15:35
awk's regexes are called EREs, but in fact they're a bit idiosyncratic. Here are probably more details than anyone cares for: wiki.alpinelinux.org/wiki/Regex– dubiousjim
Nov 10 '12 at 15:35
Thank you, grep 2.7.3 (openSUSE). I upvoted you, but I will keep question open for a while, maybe there is some trick for grep (not that I dislike
awk -- simply knowing more is better).– greenoldman
Nov 10 '12 at 15:42
Thank you, grep 2.7.3 (openSUSE). I upvoted you, but I will keep question open for a while, maybe there is some trick for grep (not that I dislike
awk -- simply knowing more is better).– greenoldman
Nov 10 '12 at 15:42
1
1
The default action is to print the matching line so the
{ print; } part isn't really necessary or useful here.– tripleee
Apr 20 '17 at 11:58
The default action is to print the matching line so the
{ print; } part isn't really necessary or useful here.– tripleee
Apr 20 '17 at 11:58
add a comment |
This is not a very good solution but illustrates a somewhat cool "trick"
function chained-grep() {
local pattern="$1"
if [[ -z "$pattern" ]]; then
cat
return
fi
shift
grep -- "$pattern" | chained-grep "$@"
}
cat something | chained-grep all patterns must match order but matter dont
Use eitherchained-grep()orfunction chained-grepbut notfunction chained-grep(): unix.stackexchange.com/questions/73750/…
– nisetama
8 hours ago
add a comment |
This is not a very good solution but illustrates a somewhat cool "trick"
function chained-grep() {
local pattern="$1"
if [[ -z "$pattern" ]]; then
cat
return
fi
shift
grep -- "$pattern" | chained-grep "$@"
}
cat something | chained-grep all patterns must match order but matter dont
Use eitherchained-grep()orfunction chained-grepbut notfunction chained-grep(): unix.stackexchange.com/questions/73750/…
– nisetama
8 hours ago
add a comment |
This is not a very good solution but illustrates a somewhat cool "trick"
function chained-grep() {
local pattern="$1"
if [[ -z "$pattern" ]]; then
cat
return
fi
shift
grep -- "$pattern" | chained-grep "$@"
}
cat something | chained-grep all patterns must match order but matter dont
This is not a very good solution but illustrates a somewhat cool "trick"
function chained-grep() {
local pattern="$1"
if [[ -z "$pattern" ]]; then
cat
return
fi
shift
grep -- "$pattern" | chained-grep "$@"
}
cat something | chained-grep all patterns must match order but matter dont
answered Nov 26 '16 at 22:13
olejorgenbolejorgenb
48647
48647
Use eitherchained-grep()orfunction chained-grepbut notfunction chained-grep(): unix.stackexchange.com/questions/73750/…
– nisetama
8 hours ago
add a comment |
Use eitherchained-grep()orfunction chained-grepbut notfunction chained-grep(): unix.stackexchange.com/questions/73750/…
– nisetama
8 hours ago
Use either
chained-grep() or function chained-grep but not function chained-grep(): unix.stackexchange.com/questions/73750/…– nisetama
8 hours ago
Use either
chained-grep() or function chained-grep but not function chained-grep(): unix.stackexchange.com/questions/73750/…– nisetama
8 hours ago
add a comment |
If patterns contains one pattern per line, you can do something like this:
awk 'NR==FNR{a[$0];next}{for(i in a)if($0!~i)next}1' patterns -
Or this matches substrings instead of regular expressions:
awk 'NR==FNR{a[$0];next}{for(i in a)if(!index($0,i))next}1' patterns -
To print all instead of no lines of the input in the case that patterns is empty, replace NR==FNR with FILENAME==ARGV[1], or with ARGIND==1 in gawk.
These functions print the lines of STDIN which contain each string specified as an argument as a substring. ga stands for grep all and gai ignores case.
ga(){ awk 'FILENAME==ARGV[1]{a[$0];next}{for(i in a)if(!index($0,i))next}1' <(printf %s\n "$@") -; }
gai(){ awk 'FILENAME==ARGV[1]{a[tolower($0)];next}{for(i in a)if(!index(tolower($0),i))next}1' <(printf %s\n "$@") -; }
add a comment |
If patterns contains one pattern per line, you can do something like this:
awk 'NR==FNR{a[$0];next}{for(i in a)if($0!~i)next}1' patterns -
Or this matches substrings instead of regular expressions:
awk 'NR==FNR{a[$0];next}{for(i in a)if(!index($0,i))next}1' patterns -
To print all instead of no lines of the input in the case that patterns is empty, replace NR==FNR with FILENAME==ARGV[1], or with ARGIND==1 in gawk.
These functions print the lines of STDIN which contain each string specified as an argument as a substring. ga stands for grep all and gai ignores case.
ga(){ awk 'FILENAME==ARGV[1]{a[$0];next}{for(i in a)if(!index($0,i))next}1' <(printf %s\n "$@") -; }
gai(){ awk 'FILENAME==ARGV[1]{a[tolower($0)];next}{for(i in a)if(!index(tolower($0),i))next}1' <(printf %s\n "$@") -; }
add a comment |
If patterns contains one pattern per line, you can do something like this:
awk 'NR==FNR{a[$0];next}{for(i in a)if($0!~i)next}1' patterns -
Or this matches substrings instead of regular expressions:
awk 'NR==FNR{a[$0];next}{for(i in a)if(!index($0,i))next}1' patterns -
To print all instead of no lines of the input in the case that patterns is empty, replace NR==FNR with FILENAME==ARGV[1], or with ARGIND==1 in gawk.
These functions print the lines of STDIN which contain each string specified as an argument as a substring. ga stands for grep all and gai ignores case.
ga(){ awk 'FILENAME==ARGV[1]{a[$0];next}{for(i in a)if(!index($0,i))next}1' <(printf %s\n "$@") -; }
gai(){ awk 'FILENAME==ARGV[1]{a[tolower($0)];next}{for(i in a)if(!index(tolower($0),i))next}1' <(printf %s\n "$@") -; }
If patterns contains one pattern per line, you can do something like this:
awk 'NR==FNR{a[$0];next}{for(i in a)if($0!~i)next}1' patterns -
Or this matches substrings instead of regular expressions:
awk 'NR==FNR{a[$0];next}{for(i in a)if(!index($0,i))next}1' patterns -
To print all instead of no lines of the input in the case that patterns is empty, replace NR==FNR with FILENAME==ARGV[1], or with ARGIND==1 in gawk.
These functions print the lines of STDIN which contain each string specified as an argument as a substring. ga stands for grep all and gai ignores case.
ga(){ awk 'FILENAME==ARGV[1]{a[$0];next}{for(i in a)if(!index($0,i))next}1' <(printf %s\n "$@") -; }
gai(){ awk 'FILENAME==ARGV[1]{a[tolower($0)];next}{for(i in a)if(!index(tolower($0),i))next}1' <(printf %s\n "$@") -; }
edited Jan 4 at 12:01
answered Mar 18 '16 at 15:25
nisetamanisetama
55946
55946
add a comment |
add a comment |
git grep
Here is the syntax using git grep combining multiple patterns using Boolean expressions:
git grep -e pattern1 --and -e pattern2 --and -e pattern3
The above command will print lines matching all the patterns at once.
If the files aren't under version control, add --no-index param.
Search files in the current directory that is not managed by Git.
Check man git-grep for help.
See also: Check if all of multiple strings or regexes exist in a file.
add a comment |
git grep
Here is the syntax using git grep combining multiple patterns using Boolean expressions:
git grep -e pattern1 --and -e pattern2 --and -e pattern3
The above command will print lines matching all the patterns at once.
If the files aren't under version control, add --no-index param.
Search files in the current directory that is not managed by Git.
Check man git-grep for help.
See also: Check if all of multiple strings or regexes exist in a file.
add a comment |
git grep
Here is the syntax using git grep combining multiple patterns using Boolean expressions:
git grep -e pattern1 --and -e pattern2 --and -e pattern3
The above command will print lines matching all the patterns at once.
If the files aren't under version control, add --no-index param.
Search files in the current directory that is not managed by Git.
Check man git-grep for help.
See also: Check if all of multiple strings or regexes exist in a file.
git grep
Here is the syntax using git grep combining multiple patterns using Boolean expressions:
git grep -e pattern1 --and -e pattern2 --and -e pattern3
The above command will print lines matching all the patterns at once.
If the files aren't under version control, add --no-index param.
Search files in the current directory that is not managed by Git.
Check man git-grep for help.
See also: Check if all of multiple strings or regexes exist in a file.
edited Apr 15 '18 at 1:57
answered Apr 11 '18 at 0:53
kenorbkenorb
8,501370106
8,501370106
add a comment |
add a comment |
This shell command may help:
eval "</dev/stdin $(printf "|grep '%s'" pattern1 pattern2)" FILE
However it's easier if all your patterns are stored in the file, so you can define the following alias:
alias grep-all="cat $(xargs printf '| grep "%s"' < patterns.txt)"
and use it as:
cat text.txt | grep-all
You can of course modify the alias depending on your required syntax, so with this alias:
alias grep-all="</dev/stdin $(xargs printf '|grep "%s"' < patterns.txt)"
you can use just a single command, e.g.
grep-all text.txt
For more ideas, check also: Match all patterns from file at once.
For AND operation per file, see: Check if all of multiple strings or regexes exist in a file.
Your first command seems to search only for the last pattern. It’s not clear what you are trying to accomplish with</dev/stdin. I couldn’t get your second command to work at all without changing it.
– G-Man
Aug 17 '18 at 15:02
add a comment |
This shell command may help:
eval "</dev/stdin $(printf "|grep '%s'" pattern1 pattern2)" FILE
However it's easier if all your patterns are stored in the file, so you can define the following alias:
alias grep-all="cat $(xargs printf '| grep "%s"' < patterns.txt)"
and use it as:
cat text.txt | grep-all
You can of course modify the alias depending on your required syntax, so with this alias:
alias grep-all="</dev/stdin $(xargs printf '|grep "%s"' < patterns.txt)"
you can use just a single command, e.g.
grep-all text.txt
For more ideas, check also: Match all patterns from file at once.
For AND operation per file, see: Check if all of multiple strings or regexes exist in a file.
Your first command seems to search only for the last pattern. It’s not clear what you are trying to accomplish with</dev/stdin. I couldn’t get your second command to work at all without changing it.
– G-Man
Aug 17 '18 at 15:02
add a comment |
This shell command may help:
eval "</dev/stdin $(printf "|grep '%s'" pattern1 pattern2)" FILE
However it's easier if all your patterns are stored in the file, so you can define the following alias:
alias grep-all="cat $(xargs printf '| grep "%s"' < patterns.txt)"
and use it as:
cat text.txt | grep-all
You can of course modify the alias depending on your required syntax, so with this alias:
alias grep-all="</dev/stdin $(xargs printf '|grep "%s"' < patterns.txt)"
you can use just a single command, e.g.
grep-all text.txt
For more ideas, check also: Match all patterns from file at once.
For AND operation per file, see: Check if all of multiple strings or regexes exist in a file.
This shell command may help:
eval "</dev/stdin $(printf "|grep '%s'" pattern1 pattern2)" FILE
However it's easier if all your patterns are stored in the file, so you can define the following alias:
alias grep-all="cat $(xargs printf '| grep "%s"' < patterns.txt)"
and use it as:
cat text.txt | grep-all
You can of course modify the alias depending on your required syntax, so with this alias:
alias grep-all="</dev/stdin $(xargs printf '|grep "%s"' < patterns.txt)"
you can use just a single command, e.g.
grep-all text.txt
For more ideas, check also: Match all patterns from file at once.
For AND operation per file, see: Check if all of multiple strings or regexes exist in a file.
edited Apr 19 '18 at 18:10
answered Dec 22 '16 at 16:01
kenorbkenorb
8,501370106
8,501370106
Your first command seems to search only for the last pattern. It’s not clear what you are trying to accomplish with</dev/stdin. I couldn’t get your second command to work at all without changing it.
– G-Man
Aug 17 '18 at 15:02
add a comment |
Your first command seems to search only for the last pattern. It’s not clear what you are trying to accomplish with</dev/stdin. I couldn’t get your second command to work at all without changing it.
– G-Man
Aug 17 '18 at 15:02
Your first command seems to search only for the last pattern. It’s not clear what you are trying to accomplish with
</dev/stdin. I couldn’t get your second command to work at all without changing it.– G-Man
Aug 17 '18 at 15:02
Your first command seems to search only for the last pattern. It’s not clear what you are trying to accomplish with
</dev/stdin. I couldn’t get your second command to work at all without changing it.– G-Man
Aug 17 '18 at 15:02
add a comment |
ripgrep
Here is the example using rg:
rg -N '(?P<p1>.*pattern1.*)(?P<p2>.*pattern2.*)(?P<p3>.*pattern3.*)' file.txt
It's one of the quickest grepping tools, since it's built on top of Rust's regex engine which uses finite automata, SIMD and aggressive literal optimizations to make searching very fast.
See also related feature request at GH-875.
add a comment |
ripgrep
Here is the example using rg:
rg -N '(?P<p1>.*pattern1.*)(?P<p2>.*pattern2.*)(?P<p3>.*pattern3.*)' file.txt
It's one of the quickest grepping tools, since it's built on top of Rust's regex engine which uses finite automata, SIMD and aggressive literal optimizations to make searching very fast.
See also related feature request at GH-875.
add a comment |
ripgrep
Here is the example using rg:
rg -N '(?P<p1>.*pattern1.*)(?P<p2>.*pattern2.*)(?P<p3>.*pattern3.*)' file.txt
It's one of the quickest grepping tools, since it's built on top of Rust's regex engine which uses finite automata, SIMD and aggressive literal optimizations to make searching very fast.
See also related feature request at GH-875.
ripgrep
Here is the example using rg:
rg -N '(?P<p1>.*pattern1.*)(?P<p2>.*pattern2.*)(?P<p3>.*pattern3.*)' file.txt
It's one of the quickest grepping tools, since it's built on top of Rust's regex engine which uses finite automata, SIMD and aggressive literal optimizations to make searching very fast.
See also related feature request at GH-875.
edited Apr 11 '18 at 9:18
answered Apr 11 '18 at 1:19
kenorbkenorb
8,501370106
8,501370106
add a comment |
add a comment |
Here's my take, and this works for words in multiple lines:
Use find . -type f followed by as many -exec grep -q 'first_word' {} ;
and the last keyword with -exec grep -l 'nth_word' {} ;
-q quiet / silent -l show files with matches
The following returns list of filenames with words 'rabbit' and 'hole' in them: find . -type f -exec grep -q 'rabbit' {} ; -exec grep -l 'hole' {} ;
New contributor
StackRover is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.
add a comment |
Here's my take, and this works for words in multiple lines:
Use find . -type f followed by as many -exec grep -q 'first_word' {} ;
and the last keyword with -exec grep -l 'nth_word' {} ;
-q quiet / silent -l show files with matches
The following returns list of filenames with words 'rabbit' and 'hole' in them: find . -type f -exec grep -q 'rabbit' {} ; -exec grep -l 'hole' {} ;
New contributor
StackRover is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.
add a comment |
Here's my take, and this works for words in multiple lines:
Use find . -type f followed by as many -exec grep -q 'first_word' {} ;
and the last keyword with -exec grep -l 'nth_word' {} ;
-q quiet / silent -l show files with matches
The following returns list of filenames with words 'rabbit' and 'hole' in them: find . -type f -exec grep -q 'rabbit' {} ; -exec grep -l 'hole' {} ;
New contributor
StackRover is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.
Here's my take, and this works for words in multiple lines:
Use find . -type f followed by as many -exec grep -q 'first_word' {} ;
and the last keyword with -exec grep -l 'nth_word' {} ;
-q quiet / silent -l show files with matches
The following returns list of filenames with words 'rabbit' and 'hole' in them: find . -type f -exec grep -q 'rabbit' {} ; -exec grep -l 'hole' {} ;
New contributor
StackRover is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.
edited 7 mins ago
New contributor
StackRover is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.
answered 12 mins ago
StackRoverStackRover
1011
1011
New contributor
StackRover is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.
New contributor
StackRover is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.
StackRover is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.
add a comment |
add a comment |
To find ALL of the words (or patterns), you can run grep in FOR loop.
The main advantage here, is searching from a list of regexs.
EDIT my answer with a real example:
# search_all_regex_and_error_if_missing.sh
find_list="
^a+$
^b+$
^h+$
^d+$
"
for item in $find_list; do
if grep -E "$item" file_to_search_within.txt
then
echo "$item found in file."
else
echo "Error: $item not found in file. Exiting!"
exit 1
fi
done
Now let's run it on this file:
hhhhhhhhhh
aaaaaaa
bbbbbbbbb
ababbabaabbaaa
ccccccc
dsfsdf
bbbb
cccdd
aa
caa
# ./search_all_regex_and_error_if_missing.sh
aaaaaaa aa
^a+$ found in file.
bbbbbbbbb bbbb
^b+$ found in file.
hhhhhhhhhh
^h+$ found in file.
Error: ^d+$ not found in file. Exiting!
1
Your logic is faulty -- I asked forALLoperator, your code works asORoperator, notAND. And btw. for that (OR) is much easier solution given right in the question.
– greenoldman
Aug 14 '18 at 22:18
@greenoldman The logic is simple: The for will loop on ALL of the words/patterns in the list, and if it is found in file - will print it. So just remove the else if you don't need action in case word was not found.
– Noam Manos
Aug 16 '18 at 15:07
I understand your logic as well as my question -- I was asking aboutANDoperator, meaning the file is only a positive hit if it matches pattern A and pattern B and pattern C and...ANDIn you case file is positive hit if it matches pattern A or pattern B or... Do you see the difference now?
– greenoldman
Aug 17 '18 at 6:19
@greenoldman not sure why you think this loop does not check AND condition for all patterns? So I've edited my answer with a real example: It will search in file for all regex of list, and on the first one which is missing - will exit with error.
– Noam Manos
Aug 19 '18 at 15:04
You have it right in front of your eyes, you have positive match just after first match is executed. You should have "collect" all outcomes and computeANDon them. Then you should rewrite the script to run on multiple files -- then maybe you realize that the question is already answered and your attempt does not bring anything to the table, sorry.
– greenoldman
Aug 20 '18 at 5:56
|
show 3 more comments
To find ALL of the words (or patterns), you can run grep in FOR loop.
The main advantage here, is searching from a list of regexs.
EDIT my answer with a real example:
# search_all_regex_and_error_if_missing.sh
find_list="
^a+$
^b+$
^h+$
^d+$
"
for item in $find_list; do
if grep -E "$item" file_to_search_within.txt
then
echo "$item found in file."
else
echo "Error: $item not found in file. Exiting!"
exit 1
fi
done
Now let's run it on this file:
hhhhhhhhhh
aaaaaaa
bbbbbbbbb
ababbabaabbaaa
ccccccc
dsfsdf
bbbb
cccdd
aa
caa
# ./search_all_regex_and_error_if_missing.sh
aaaaaaa aa
^a+$ found in file.
bbbbbbbbb bbbb
^b+$ found in file.
hhhhhhhhhh
^h+$ found in file.
Error: ^d+$ not found in file. Exiting!
1
Your logic is faulty -- I asked forALLoperator, your code works asORoperator, notAND. And btw. for that (OR) is much easier solution given right in the question.
– greenoldman
Aug 14 '18 at 22:18
@greenoldman The logic is simple: The for will loop on ALL of the words/patterns in the list, and if it is found in file - will print it. So just remove the else if you don't need action in case word was not found.
– Noam Manos
Aug 16 '18 at 15:07
I understand your logic as well as my question -- I was asking aboutANDoperator, meaning the file is only a positive hit if it matches pattern A and pattern B and pattern C and...ANDIn you case file is positive hit if it matches pattern A or pattern B or... Do you see the difference now?
– greenoldman
Aug 17 '18 at 6:19
@greenoldman not sure why you think this loop does not check AND condition for all patterns? So I've edited my answer with a real example: It will search in file for all regex of list, and on the first one which is missing - will exit with error.
– Noam Manos
Aug 19 '18 at 15:04
You have it right in front of your eyes, you have positive match just after first match is executed. You should have "collect" all outcomes and computeANDon them. Then you should rewrite the script to run on multiple files -- then maybe you realize that the question is already answered and your attempt does not bring anything to the table, sorry.
– greenoldman
Aug 20 '18 at 5:56
|
show 3 more comments
To find ALL of the words (or patterns), you can run grep in FOR loop.
The main advantage here, is searching from a list of regexs.
EDIT my answer with a real example:
# search_all_regex_and_error_if_missing.sh
find_list="
^a+$
^b+$
^h+$
^d+$
"
for item in $find_list; do
if grep -E "$item" file_to_search_within.txt
then
echo "$item found in file."
else
echo "Error: $item not found in file. Exiting!"
exit 1
fi
done
Now let's run it on this file:
hhhhhhhhhh
aaaaaaa
bbbbbbbbb
ababbabaabbaaa
ccccccc
dsfsdf
bbbb
cccdd
aa
caa
# ./search_all_regex_and_error_if_missing.sh
aaaaaaa aa
^a+$ found in file.
bbbbbbbbb bbbb
^b+$ found in file.
hhhhhhhhhh
^h+$ found in file.
Error: ^d+$ not found in file. Exiting!
To find ALL of the words (or patterns), you can run grep in FOR loop.
The main advantage here, is searching from a list of regexs.
EDIT my answer with a real example:
# search_all_regex_and_error_if_missing.sh
find_list="
^a+$
^b+$
^h+$
^d+$
"
for item in $find_list; do
if grep -E "$item" file_to_search_within.txt
then
echo "$item found in file."
else
echo "Error: $item not found in file. Exiting!"
exit 1
fi
done
Now let's run it on this file:
hhhhhhhhhh
aaaaaaa
bbbbbbbbb
ababbabaabbaaa
ccccccc
dsfsdf
bbbb
cccdd
aa
caa
# ./search_all_regex_and_error_if_missing.sh
aaaaaaa aa
^a+$ found in file.
bbbbbbbbb bbbb
^b+$ found in file.
hhhhhhhhhh
^h+$ found in file.
Error: ^d+$ not found in file. Exiting!
edited Aug 19 '18 at 15:12
answered Aug 14 '18 at 6:51
Noam ManosNoam Manos
1573
1573
1
Your logic is faulty -- I asked forALLoperator, your code works asORoperator, notAND. And btw. for that (OR) is much easier solution given right in the question.
– greenoldman
Aug 14 '18 at 22:18
@greenoldman The logic is simple: The for will loop on ALL of the words/patterns in the list, and if it is found in file - will print it. So just remove the else if you don't need action in case word was not found.
– Noam Manos
Aug 16 '18 at 15:07
I understand your logic as well as my question -- I was asking aboutANDoperator, meaning the file is only a positive hit if it matches pattern A and pattern B and pattern C and...ANDIn you case file is positive hit if it matches pattern A or pattern B or... Do you see the difference now?
– greenoldman
Aug 17 '18 at 6:19
@greenoldman not sure why you think this loop does not check AND condition for all patterns? So I've edited my answer with a real example: It will search in file for all regex of list, and on the first one which is missing - will exit with error.
– Noam Manos
Aug 19 '18 at 15:04
You have it right in front of your eyes, you have positive match just after first match is executed. You should have "collect" all outcomes and computeANDon them. Then you should rewrite the script to run on multiple files -- then maybe you realize that the question is already answered and your attempt does not bring anything to the table, sorry.
– greenoldman
Aug 20 '18 at 5:56
|
show 3 more comments
1
Your logic is faulty -- I asked forALLoperator, your code works asORoperator, notAND. And btw. for that (OR) is much easier solution given right in the question.
– greenoldman
Aug 14 '18 at 22:18
@greenoldman The logic is simple: The for will loop on ALL of the words/patterns in the list, and if it is found in file - will print it. So just remove the else if you don't need action in case word was not found.
– Noam Manos
Aug 16 '18 at 15:07
I understand your logic as well as my question -- I was asking aboutANDoperator, meaning the file is only a positive hit if it matches pattern A and pattern B and pattern C and...ANDIn you case file is positive hit if it matches pattern A or pattern B or... Do you see the difference now?
– greenoldman
Aug 17 '18 at 6:19
@greenoldman not sure why you think this loop does not check AND condition for all patterns? So I've edited my answer with a real example: It will search in file for all regex of list, and on the first one which is missing - will exit with error.
– Noam Manos
Aug 19 '18 at 15:04
You have it right in front of your eyes, you have positive match just after first match is executed. You should have "collect" all outcomes and computeANDon them. Then you should rewrite the script to run on multiple files -- then maybe you realize that the question is already answered and your attempt does not bring anything to the table, sorry.
– greenoldman
Aug 20 '18 at 5:56
1
1
Your logic is faulty -- I asked for
ALL operator, your code works as OR operator, not AND. And btw. for that (OR) is much easier solution given right in the question.– greenoldman
Aug 14 '18 at 22:18
Your logic is faulty -- I asked for
ALL operator, your code works as OR operator, not AND. And btw. for that (OR) is much easier solution given right in the question.– greenoldman
Aug 14 '18 at 22:18
@greenoldman The logic is simple: The for will loop on ALL of the words/patterns in the list, and if it is found in file - will print it. So just remove the else if you don't need action in case word was not found.
– Noam Manos
Aug 16 '18 at 15:07
@greenoldman The logic is simple: The for will loop on ALL of the words/patterns in the list, and if it is found in file - will print it. So just remove the else if you don't need action in case word was not found.
– Noam Manos
Aug 16 '18 at 15:07
I understand your logic as well as my question -- I was asking about
AND operator, meaning the file is only a positive hit if it matches pattern A and pattern B and pattern C and... AND In you case file is positive hit if it matches pattern A or pattern B or... Do you see the difference now?– greenoldman
Aug 17 '18 at 6:19
I understand your logic as well as my question -- I was asking about
AND operator, meaning the file is only a positive hit if it matches pattern A and pattern B and pattern C and... AND In you case file is positive hit if it matches pattern A or pattern B or... Do you see the difference now?– greenoldman
Aug 17 '18 at 6:19
@greenoldman not sure why you think this loop does not check AND condition for all patterns? So I've edited my answer with a real example: It will search in file for all regex of list, and on the first one which is missing - will exit with error.
– Noam Manos
Aug 19 '18 at 15:04
@greenoldman not sure why you think this loop does not check AND condition for all patterns? So I've edited my answer with a real example: It will search in file for all regex of list, and on the first one which is missing - will exit with error.
– Noam Manos
Aug 19 '18 at 15:04
You have it right in front of your eyes, you have positive match just after first match is executed. You should have "collect" all outcomes and compute
AND on them. Then you should rewrite the script to run on multiple files -- then maybe you realize that the question is already answered and your attempt does not bring anything to the table, sorry.– greenoldman
Aug 20 '18 at 5:56
You have it right in front of your eyes, you have positive match just after first match is executed. You should have "collect" all outcomes and compute
AND on them. Then you should rewrite the script to run on multiple files -- then maybe you realize that the question is already answered and your attempt does not bring anything to the table, sorry.– greenoldman
Aug 20 '18 at 5:56
|
show 3 more comments
Thanks for contributing an answer to Unix & Linux Stack Exchange!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f55359%2fhow-to-run-grep-with-multiple-and-patterns%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Similar: Match all patterns from file at once
– kenorb
Dec 22 '16 at 15:26
Similar question on SO: Check if multiple strings or regexes exist in a file
– codeforester
Apr 13 '18 at 17:47