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



















  • 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










9 Answers
9






active

oldest

votes


















73














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



















19














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
























  • Use either chained-grep() or function chained-grep but not function chained-grep(): unix.stackexchange.com/questions/73750/…

    – nisetama
    8 hours ago



















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

































        0














        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' {} ;






        share|improve this answer










        New contributor




        StackRover is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
        Check out our Code of Conduct.




























          -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

























          9 Answers
          9






          active

          oldest

          votes








          9 Answers
          9






          active

          oldest

          votes









          active

          oldest

          votes






          active

          oldest

          votes









          73














          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
















          73














          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














          73












          73








          73







          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 ChazelasStéphane Chazelas

          301k55565917




          301k55565917








          • 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













          19














          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


















          19














          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
















          19












          19








          19







          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









          NetchNetch

          1,862910




          1,862910








          • 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
























          • Use either chained-grep() or function chained-grep but not function chained-grep(): unix.stackexchange.com/questions/73750/…

            – nisetama
            8 hours ago
















          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
























          • Use either chained-grep() or function chained-grep but not function chained-grep(): unix.stackexchange.com/questions/73750/…

            – nisetama
            8 hours ago














          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









          olejorgenbolejorgenb

          48647




          48647













          • 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

















          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











          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 Jan 4 at 12:01

























              answered Mar 18 '16 at 15:25









              nisetamanisetama

              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









                      kenorbkenorb

                      8,501370106




                      8,501370106























                          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









                          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



















                          • 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









                              kenorbkenorb

                              8,501370106




                              8,501370106























                                  0














                                  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' {} ;






                                  share|improve this answer










                                  New contributor




                                  StackRover is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
                                  Check out our Code of Conduct.

























                                    0














                                    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' {} ;






                                    share|improve this answer










                                    New contributor




                                    StackRover is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
                                    Check out our Code of Conduct.























                                      0












                                      0








                                      0







                                      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' {} ;






                                      share|improve this answer










                                      New contributor




                                      StackRover is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
                                      Check out our Code of Conduct.










                                      Here's my take, and this works for words in multiple lines:



                                      Use find . -type f followed by as many
                                      -exec grep -q 'first_word' {} ;

                                      and the last keyword with
                                      -exec grep -l 'nth_word' {} ;



                                      -q quiet / silent
                                      -l show files with matches



                                      The following returns list of filenames with words 'rabbit' and 'hole' in them:
                                      find . -type f -exec grep -q 'rabbit' {} ; -exec grep -l 'hole' {} ;







                                      share|improve this answer










                                      New contributor




                                      StackRover is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
                                      Check out our Code of Conduct.









                                      share|improve this answer



                                      share|improve this answer








                                      edited 7 mins ago





















                                      New contributor




                                      StackRover is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
                                      Check out our Code of Conduct.









                                      answered 12 mins ago









                                      StackRoverStackRover

                                      1011




                                      1011




                                      New contributor




                                      StackRover is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
                                      Check out our Code of Conduct.





                                      New contributor





                                      StackRover is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
                                      Check out our Code of Conduct.






                                      StackRover is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
                                      Check out our Code of Conduct.























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




                                          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

                                          Loup dans la culture

                                          How to solve the problem of ntp “Unable to contact time server” from KDE?

                                          Connection limited (no internet access)