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
Theagrep
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 ofagrep
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 haveagrep
0.8.0 on Fedora 23. This appears to be a differentagrep
than 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 thatawk
uses ERE's, e.g. the equivalent ofgrep -E
, as opposed to the BRE's that plaingrep
uses.
– 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-grep
but 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
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 forALL
operator, your code works asOR
operator, 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 aboutAND
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
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 computeAND
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
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
Theagrep
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 ofagrep
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 haveagrep
0.8.0 on Fedora 23. This appears to be a differentagrep
than 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
Theagrep
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 ofagrep
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 haveagrep
0.8.0 on Fedora 23. This appears to be a differentagrep
than 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
Theagrep
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 ofagrep
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 haveagrep
0.8.0 on Fedora 23. This appears to be a differentagrep
than 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
Theagrep
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 ofagrep
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 haveagrep
0.8.0 on Fedora 23. This appears to be a differentagrep
than 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 thatawk
uses ERE's, e.g. the equivalent ofgrep -E
, as opposed to the BRE's that plaingrep
uses.
– 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 thatawk
uses ERE's, e.g. the equivalent ofgrep -E
, as opposed to the BRE's that plaingrep
uses.
– 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 thatawk
uses ERE's, e.g. the equivalent ofgrep -E
, as opposed to the BRE's that plaingrep
uses.
– 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 thatawk
uses ERE's, e.g. the equivalent ofgrep -E
, as opposed to the BRE's that plaingrep
uses.
– 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-grep
but 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-grep
but 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-grep
but notfunction chained-grep()
: unix.stackexchange.com/questions/73750/…
– nisetama
8 hours ago
add a comment |
Use eitherchained-grep()
orfunction chained-grep
but 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
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
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
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
edited 7 mins ago
New contributor
answered 12 mins ago
StackRoverStackRover
1011
1011
New contributor
New contributor
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 forALL
operator, your code works asOR
operator, 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 aboutAND
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
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 computeAND
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
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 forALL
operator, your code works asOR
operator, 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 aboutAND
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
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 computeAND
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
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 forALL
operator, your code works asOR
operator, 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 aboutAND
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
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 computeAND
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
1
Your logic is faulty -- I asked forALL
operator, your code works asOR
operator, 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 aboutAND
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
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 computeAND
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
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