How to run grep with multiple AND patterns?












80














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.










share|improve this question
























  • 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
















80














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.










share|improve this question
























  • 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














80












80








80


30





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.










share|improve this question















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






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Nov 13 '12 at 21:01









dubiousjim

1,9781223




1,9781223










asked Nov 10 '12 at 7:45









greenoldman

2,482104159




2,482104159












  • 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 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










8 Answers
8






active

oldest

votes


















72














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.






share|improve this answer



















  • 1




    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












  • @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




    @Raman, yours sounds like TRE agrep.
    – Stéphane Chazelas
    Sep 6 '16 at 7:01






  • 1




    @Techiee, or just awk '/p1/ && /p2/ {n++}; END {print 0+n}'
    – Stéphane Chazelas
    Jun 28 '17 at 20:23



















18














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.






share|improve this answer

















  • 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






  • 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 dislike awk -- 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





















7














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





share|improve this answer





























    7





    +50











    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 "$@") -; }





    share|improve this answer































      2














      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.






      share|improve this answer































        1














        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.






        share|improve this answer























        • 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



















        0














        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.






        share|improve this answer































          -1














          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!







          share|improve this answer



















          • 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












          • @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










          • @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











          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
          });


          }
          });














          draft saved

          draft discarded


















          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

























          8 Answers
          8






          active

          oldest

          votes








          8 Answers
          8






          active

          oldest

          votes









          active

          oldest

          votes






          active

          oldest

          votes









          72














          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.






          share|improve this answer



















          • 1




            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












          • @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




            @Raman, yours sounds like TRE agrep.
            – Stéphane Chazelas
            Sep 6 '16 at 7:01






          • 1




            @Techiee, or just awk '/p1/ && /p2/ {n++}; END {print 0+n}'
            – Stéphane Chazelas
            Jun 28 '17 at 20:23
















          72














          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.






          share|improve this answer



















          • 1




            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












          • @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




            @Raman, yours sounds like TRE agrep.
            – Stéphane Chazelas
            Sep 6 '16 at 7:01






          • 1




            @Techiee, or just awk '/p1/ && /p2/ {n++}; END {print 0+n}'
            – Stéphane Chazelas
            Jun 28 '17 at 20:23














          72












          72








          72






          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.






          share|improve this answer














          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.







          share|improve this answer














          share|improve this answer



          share|improve this answer








          edited Sep 6 '16 at 5:55

























          answered Nov 10 '12 at 20:13









          Stéphane Chazelas

          300k54564913




          300k54564913








          • 1




            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












          • @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




            @Raman, yours sounds like TRE agrep.
            – Stéphane Chazelas
            Sep 6 '16 at 7:01






          • 1




            @Techiee, or just awk '/p1/ && /p2/ {n++}; END {print 0+n}'
            – Stéphane Chazelas
            Jun 28 '17 at 20:23














          • 1




            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












          • @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




            @Raman, yours sounds like TRE agrep.
            – Stéphane Chazelas
            Sep 6 '16 at 7:01






          • 1




            @Techiee, or just awk '/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













          18














          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.






          share|improve this answer

















          • 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






          • 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 dislike awk -- 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


















          18














          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.






          share|improve this answer

















          • 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






          • 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 dislike awk -- 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
















          18












          18








          18






          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.






          share|improve this answer












          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.







          share|improve this answer












          share|improve this answer



          share|improve this answer










          answered Nov 10 '12 at 8:34









          Netch

          1,842910




          1,842910








          • 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






          • 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 dislike awk -- 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




            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




            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








          • 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













          7














          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





          share|improve this answer


























            7














            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





            share|improve this answer
























              7












              7








              7






              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





              share|improve this answer












              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






              share|improve this answer












              share|improve this answer



              share|improve this answer










              answered Nov 26 '16 at 22:13









              olejorgenb

              48647




              48647























                  7





                  +50











                  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 "$@") -; }





                  share|improve this answer




























                    7





                    +50











                    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 "$@") -; }





                    share|improve this answer


























                      7





                      +50







                      7





                      +50



                      7




                      +50






                      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 "$@") -; }





                      share|improve this answer
















                      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 "$@") -; }






                      share|improve this answer














                      share|improve this answer



                      share|improve this answer








                      edited yesterday

























                      answered Mar 18 '16 at 15:25









                      nisetama

                      55946




                      55946























                          2














                          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.






                          share|improve this answer




























                            2














                            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.






                            share|improve this answer


























                              2












                              2








                              2






                              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.






                              share|improve this answer














                              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.







                              share|improve this answer














                              share|improve this answer



                              share|improve this answer








                              edited Apr 15 '18 at 1:57

























                              answered Apr 11 '18 at 0:53









                              kenorb

                              8,391370106




                              8,391370106























                                  1














                                  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.






                                  share|improve this answer























                                  • 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
















                                  1














                                  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.






                                  share|improve this answer























                                  • 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














                                  1












                                  1








                                  1






                                  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.






                                  share|improve this answer














                                  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.







                                  share|improve this answer














                                  share|improve this answer



                                  share|improve this answer








                                  edited Apr 19 '18 at 18:10

























                                  answered Dec 22 '16 at 16:01









                                  kenorb

                                  8,391370106




                                  8,391370106












                                  • 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




                                  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











                                  0














                                  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.






                                  share|improve this answer




























                                    0














                                    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.






                                    share|improve this answer


























                                      0












                                      0








                                      0






                                      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.






                                      share|improve this answer














                                      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.







                                      share|improve this answer














                                      share|improve this answer



                                      share|improve this answer








                                      edited Apr 11 '18 at 9:18

























                                      answered Apr 11 '18 at 1:19









                                      kenorb

                                      8,391370106




                                      8,391370106























                                          -1














                                          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!







                                          share|improve this answer



















                                          • 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












                                          • @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










                                          • @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
















                                          -1














                                          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!







                                          share|improve this answer



















                                          • 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












                                          • @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










                                          • @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














                                          -1












                                          -1








                                          -1






                                          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!







                                          share|improve this answer














                                          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!








                                          share|improve this answer














                                          share|improve this answer



                                          share|improve this answer








                                          edited Aug 19 '18 at 15:12

























                                          answered Aug 14 '18 at 6:51









                                          Noam Manos

                                          1573




                                          1573








                                          • 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












                                          • @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










                                          • @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














                                          • 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












                                          • @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










                                          • @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








                                          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


















                                          draft saved

                                          draft discarded




















































                                          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.





                                          Some of your past answers have not been well-received, and you're in danger of being blocked from answering.


                                          Please pay close attention to the following guidance:


                                          • 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.




                                          draft saved


                                          draft discarded














                                          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





















































                                          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







                                          Popular posts from this blog

                                          How to make a Squid Proxy server?

                                          Is this a new Fibonacci Identity?

                                          19世紀