grep range of numbers in a text file

The name of the pictureThe name of the pictureThe name of the pictureClash Royale CLAN TAG#URR8PPP











up vote
0
down vote

favorite












I have following text in a text file



$ cat test
20180618:
20180619:
20180620:
20180621:
20180622:
20180623:
20180624:


I have tried to grep with the range of numbers like below,



$ grep 20180619..21 test
grep: 20180619: No such file or directory
grep: 20180620: No such file or directory
grep: 20180621: No such file or directory


I'm getting above error on both ZSH and bash.
It seems grep taking the search string as files.



I have tried the another way:



$ grep 201806* test 
zsh: no matches found: 201806*


I am getting that error only on ZSH.
What is the right way to use * in ZSH and how can I tell grep to grep range of numbers?







share|improve this question

























    up vote
    0
    down vote

    favorite












    I have following text in a text file



    $ cat test
    20180618:
    20180619:
    20180620:
    20180621:
    20180622:
    20180623:
    20180624:


    I have tried to grep with the range of numbers like below,



    $ grep 20180619..21 test
    grep: 20180619: No such file or directory
    grep: 20180620: No such file or directory
    grep: 20180621: No such file or directory


    I'm getting above error on both ZSH and bash.
    It seems grep taking the search string as files.



    I have tried the another way:



    $ grep 201806* test 
    zsh: no matches found: 201806*


    I am getting that error only on ZSH.
    What is the right way to use * in ZSH and how can I tell grep to grep range of numbers?







    share|improve this question























      up vote
      0
      down vote

      favorite









      up vote
      0
      down vote

      favorite











      I have following text in a text file



      $ cat test
      20180618:
      20180619:
      20180620:
      20180621:
      20180622:
      20180623:
      20180624:


      I have tried to grep with the range of numbers like below,



      $ grep 20180619..21 test
      grep: 20180619: No such file or directory
      grep: 20180620: No such file or directory
      grep: 20180621: No such file or directory


      I'm getting above error on both ZSH and bash.
      It seems grep taking the search string as files.



      I have tried the another way:



      $ grep 201806* test 
      zsh: no matches found: 201806*


      I am getting that error only on ZSH.
      What is the right way to use * in ZSH and how can I tell grep to grep range of numbers?







      share|improve this question













      I have following text in a text file



      $ cat test
      20180618:
      20180619:
      20180620:
      20180621:
      20180622:
      20180623:
      20180624:


      I have tried to grep with the range of numbers like below,



      $ grep 20180619..21 test
      grep: 20180619: No such file or directory
      grep: 20180620: No such file or directory
      grep: 20180621: No such file or directory


      I'm getting above error on both ZSH and bash.
      It seems grep taking the search string as files.



      I have tried the another way:



      $ grep 201806* test 
      zsh: no matches found: 201806*


      I am getting that error only on ZSH.
      What is the right way to use * in ZSH and how can I tell grep to grep range of numbers?









      share|improve this question












      share|improve this question




      share|improve this question








      edited Jun 21 at 10:56









      Jeff Schaller

      30.8k846104




      30.8k846104









      asked Jun 21 at 10:07









      smc

      296




      296




















          4 Answers
          4






          active

          oldest

          votes

















          up vote
          1
          down vote



          accepted










          grep 20180619..21 test


          is expanded by the shell to:



          grep 20180619 20180620 20180621 test


          Which grep understands as looking for 20180619 inside the 3 files, 20180620, 20180621 and test.



          If you change it to:



          grep -e20180619..21 test


          Then that's expanded to:



          grep -e20180619 -e20180620 -e20180621 test


          Which gives 3 expressions for grep to search for in test.



          Or you can do:



          printf '%sn' 20180619..21 | grep -f - test


          Where we pass the expressions as a number of lines of input to grep (with some implementations, you may need /dev/stdin in place of -).



          With zsh specifically, you can also make it:



          numbers=(19..21 25 31)
          grep -E "201801($(j:)" test


          Where we use the (j:|:) parameter expansion flag to join the array elements with | (the extended regular expression alternation operator) so it can be used as an ERE.



          Or you could tie that array to a regexp scalar with:



          $ typeset -T re numbers '|'
          $ numbers=(19..21 25 31)
          $ echo $re
          19|20|21|25|31


          While regular expressions usually don't have number range matching capabilities, zsh patterns (which with extendedglob are functionally equivalent to regular expressions) do with the <x-y> operator (only for sequences of decimal digits):



          print -rl -- $(M)$(f)"$(<test)":#*201806<19-21>*





          share|improve this answer























          • +1 for grep -e20180619..21 test.
            – smc
            Jun 22 at 15:02

















          up vote
          6
          down vote













          Yes, grep only treats its first argument as a regular expression by default.



          This means that



          grep 1..9 file


          which expands to



          grep 1 2 3 4 5 6 7 8 9 file


          would invoke grep with 1 as the expression to match in the other operands, and that these other operands would be expected to be filenames.



          Your other command:



          grep 201806* test


          This would try to match 201806* as a filename globbing pattern. You have no files whose names start with 201806 in the current directory so the zsh shell fails to expand the pattern and gives you the error message no matches found.



          In other Bourne-like shells, if the pattern hadn't matched any filenames, it would have remained unexpanded and used as the regular expression with grep. The expression 201806*, when taken as a regular expression, matches 20180 followed by zero or more 6 characters, e.g. 2018066666.



          Instead, you may want to construct a regular expression to match your range:



          grep -E '201806(19|20|21)' test


          or



          grep -E '201806(19|2[01])' test


          The -E is needed to have grep understand | (alternation) in the expression (this alternation makes it an extended regular expression).




          You could also construct a regular expression from a brace expansion:



          set -- 19..21
          re=$( IFS='|'; printf '201806(%s)' "$*" )

          grep -E "$re" test


          This would first set the positional parameters, $1, $2 and $3, to the wanted numbers in the range. The variable re would then be set to 201806(%s) where printf would replace %s with these numbers delimited by |.



          The grep call would use 201806(19|20|21) as the regular expression.






          share|improve this answer























          • Or it could be done with a newline separated list of fixed strings maybe? i.e. printf '%sn' 20180619..21 | grep -Ff- test
            – steeldriver
            Jun 21 at 12:06











          • @steeldriver Yes, but I think you have to use /dev/stdin as the input file name, unless your grep interprets - as standard input.
            – Kusalananda
            Jun 21 at 12:08










          • It does - I didn't realize others didn't :(
            – steeldriver
            Jun 21 at 12:10

















          up vote
          2
          down vote













          unquoted strings are interpreted by the shell before command is executed, in your case, the command you tried would be expanded to grep 20180619 20180620 20180621 test



          $ echo grep 20180619..21 test
          grep 20180619 20180620 20180621 test


          One workaround is to specify regular expression alternation:



          $ grep -E '201806(19|20|21)' test
          20180619:
          20180620:
          20180621:


          You can construct a numeric range with regular expressions, but it is not easy. See https://www.regular-expressions.info/numericranges.html for details





          Another option is to use awk



          $ awk -F: '$1>=20180619 && $1<=20180621' ip.txt
          20180619:
          20180620:
          20180621:


          Here, we split the line on : and then compare the first field $1 with range required






          share|improve this answer






























            up vote
            1
            down vote














            1. POSIX shell (no bash) with utils:



              seq 20180618 20180624 | grep -f - test



            2. numgrep:



              numgrep '/20180618..20180624/' < test






            share|improve this answer



















            • 2




              (just to clear some possible confusion, note that neither seq nor numgrep are POSIX commands).
              – Stéphane Chazelas
              Jun 22 at 17:13










            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',
            convertImagesToLinks: false,
            noModals: false,
            showLowRepImageUploadWarning: true,
            reputationToPostImages: null,
            bindNavPrevention: true,
            postfix: "",
            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%2f451059%2fgrep-range-of-numbers-in-a-text-file%23new-answer', 'question_page');

            );

            Post as a guest






























            4 Answers
            4






            active

            oldest

            votes








            4 Answers
            4






            active

            oldest

            votes









            active

            oldest

            votes






            active

            oldest

            votes








            up vote
            1
            down vote



            accepted










            grep 20180619..21 test


            is expanded by the shell to:



            grep 20180619 20180620 20180621 test


            Which grep understands as looking for 20180619 inside the 3 files, 20180620, 20180621 and test.



            If you change it to:



            grep -e20180619..21 test


            Then that's expanded to:



            grep -e20180619 -e20180620 -e20180621 test


            Which gives 3 expressions for grep to search for in test.



            Or you can do:



            printf '%sn' 20180619..21 | grep -f - test


            Where we pass the expressions as a number of lines of input to grep (with some implementations, you may need /dev/stdin in place of -).



            With zsh specifically, you can also make it:



            numbers=(19..21 25 31)
            grep -E "201801($(j:)" test


            Where we use the (j:|:) parameter expansion flag to join the array elements with | (the extended regular expression alternation operator) so it can be used as an ERE.



            Or you could tie that array to a regexp scalar with:



            $ typeset -T re numbers '|'
            $ numbers=(19..21 25 31)
            $ echo $re
            19|20|21|25|31


            While regular expressions usually don't have number range matching capabilities, zsh patterns (which with extendedglob are functionally equivalent to regular expressions) do with the <x-y> operator (only for sequences of decimal digits):



            print -rl -- $(M)$(f)"$(<test)":#*201806<19-21>*





            share|improve this answer























            • +1 for grep -e20180619..21 test.
              – smc
              Jun 22 at 15:02














            up vote
            1
            down vote



            accepted










            grep 20180619..21 test


            is expanded by the shell to:



            grep 20180619 20180620 20180621 test


            Which grep understands as looking for 20180619 inside the 3 files, 20180620, 20180621 and test.



            If you change it to:



            grep -e20180619..21 test


            Then that's expanded to:



            grep -e20180619 -e20180620 -e20180621 test


            Which gives 3 expressions for grep to search for in test.



            Or you can do:



            printf '%sn' 20180619..21 | grep -f - test


            Where we pass the expressions as a number of lines of input to grep (with some implementations, you may need /dev/stdin in place of -).



            With zsh specifically, you can also make it:



            numbers=(19..21 25 31)
            grep -E "201801($(j:)" test


            Where we use the (j:|:) parameter expansion flag to join the array elements with | (the extended regular expression alternation operator) so it can be used as an ERE.



            Or you could tie that array to a regexp scalar with:



            $ typeset -T re numbers '|'
            $ numbers=(19..21 25 31)
            $ echo $re
            19|20|21|25|31


            While regular expressions usually don't have number range matching capabilities, zsh patterns (which with extendedglob are functionally equivalent to regular expressions) do with the <x-y> operator (only for sequences of decimal digits):



            print -rl -- $(M)$(f)"$(<test)":#*201806<19-21>*





            share|improve this answer























            • +1 for grep -e20180619..21 test.
              – smc
              Jun 22 at 15:02












            up vote
            1
            down vote



            accepted







            up vote
            1
            down vote



            accepted






            grep 20180619..21 test


            is expanded by the shell to:



            grep 20180619 20180620 20180621 test


            Which grep understands as looking for 20180619 inside the 3 files, 20180620, 20180621 and test.



            If you change it to:



            grep -e20180619..21 test


            Then that's expanded to:



            grep -e20180619 -e20180620 -e20180621 test


            Which gives 3 expressions for grep to search for in test.



            Or you can do:



            printf '%sn' 20180619..21 | grep -f - test


            Where we pass the expressions as a number of lines of input to grep (with some implementations, you may need /dev/stdin in place of -).



            With zsh specifically, you can also make it:



            numbers=(19..21 25 31)
            grep -E "201801($(j:)" test


            Where we use the (j:|:) parameter expansion flag to join the array elements with | (the extended regular expression alternation operator) so it can be used as an ERE.



            Or you could tie that array to a regexp scalar with:



            $ typeset -T re numbers '|'
            $ numbers=(19..21 25 31)
            $ echo $re
            19|20|21|25|31


            While regular expressions usually don't have number range matching capabilities, zsh patterns (which with extendedglob are functionally equivalent to regular expressions) do with the <x-y> operator (only for sequences of decimal digits):



            print -rl -- $(M)$(f)"$(<test)":#*201806<19-21>*





            share|improve this answer















            grep 20180619..21 test


            is expanded by the shell to:



            grep 20180619 20180620 20180621 test


            Which grep understands as looking for 20180619 inside the 3 files, 20180620, 20180621 and test.



            If you change it to:



            grep -e20180619..21 test


            Then that's expanded to:



            grep -e20180619 -e20180620 -e20180621 test


            Which gives 3 expressions for grep to search for in test.



            Or you can do:



            printf '%sn' 20180619..21 | grep -f - test


            Where we pass the expressions as a number of lines of input to grep (with some implementations, you may need /dev/stdin in place of -).



            With zsh specifically, you can also make it:



            numbers=(19..21 25 31)
            grep -E "201801($(j:)" test


            Where we use the (j:|:) parameter expansion flag to join the array elements with | (the extended regular expression alternation operator) so it can be used as an ERE.



            Or you could tie that array to a regexp scalar with:



            $ typeset -T re numbers '|'
            $ numbers=(19..21 25 31)
            $ echo $re
            19|20|21|25|31


            While regular expressions usually don't have number range matching capabilities, zsh patterns (which with extendedglob are functionally equivalent to regular expressions) do with the <x-y> operator (only for sequences of decimal digits):



            print -rl -- $(M)$(f)"$(<test)":#*201806<19-21>*






            share|improve this answer















            share|improve this answer



            share|improve this answer








            edited Jun 22 at 17:28


























            answered Jun 22 at 13:51









            Stéphane Chazelas

            278k52513844




            278k52513844











            • +1 for grep -e20180619..21 test.
              – smc
              Jun 22 at 15:02
















            • +1 for grep -e20180619..21 test.
              – smc
              Jun 22 at 15:02















            +1 for grep -e20180619..21 test.
            – smc
            Jun 22 at 15:02




            +1 for grep -e20180619..21 test.
            – smc
            Jun 22 at 15:02












            up vote
            6
            down vote













            Yes, grep only treats its first argument as a regular expression by default.



            This means that



            grep 1..9 file


            which expands to



            grep 1 2 3 4 5 6 7 8 9 file


            would invoke grep with 1 as the expression to match in the other operands, and that these other operands would be expected to be filenames.



            Your other command:



            grep 201806* test


            This would try to match 201806* as a filename globbing pattern. You have no files whose names start with 201806 in the current directory so the zsh shell fails to expand the pattern and gives you the error message no matches found.



            In other Bourne-like shells, if the pattern hadn't matched any filenames, it would have remained unexpanded and used as the regular expression with grep. The expression 201806*, when taken as a regular expression, matches 20180 followed by zero or more 6 characters, e.g. 2018066666.



            Instead, you may want to construct a regular expression to match your range:



            grep -E '201806(19|20|21)' test


            or



            grep -E '201806(19|2[01])' test


            The -E is needed to have grep understand | (alternation) in the expression (this alternation makes it an extended regular expression).




            You could also construct a regular expression from a brace expansion:



            set -- 19..21
            re=$( IFS='|'; printf '201806(%s)' "$*" )

            grep -E "$re" test


            This would first set the positional parameters, $1, $2 and $3, to the wanted numbers in the range. The variable re would then be set to 201806(%s) where printf would replace %s with these numbers delimited by |.



            The grep call would use 201806(19|20|21) as the regular expression.






            share|improve this answer























            • Or it could be done with a newline separated list of fixed strings maybe? i.e. printf '%sn' 20180619..21 | grep -Ff- test
              – steeldriver
              Jun 21 at 12:06











            • @steeldriver Yes, but I think you have to use /dev/stdin as the input file name, unless your grep interprets - as standard input.
              – Kusalananda
              Jun 21 at 12:08










            • It does - I didn't realize others didn't :(
              – steeldriver
              Jun 21 at 12:10














            up vote
            6
            down vote













            Yes, grep only treats its first argument as a regular expression by default.



            This means that



            grep 1..9 file


            which expands to



            grep 1 2 3 4 5 6 7 8 9 file


            would invoke grep with 1 as the expression to match in the other operands, and that these other operands would be expected to be filenames.



            Your other command:



            grep 201806* test


            This would try to match 201806* as a filename globbing pattern. You have no files whose names start with 201806 in the current directory so the zsh shell fails to expand the pattern and gives you the error message no matches found.



            In other Bourne-like shells, if the pattern hadn't matched any filenames, it would have remained unexpanded and used as the regular expression with grep. The expression 201806*, when taken as a regular expression, matches 20180 followed by zero or more 6 characters, e.g. 2018066666.



            Instead, you may want to construct a regular expression to match your range:



            grep -E '201806(19|20|21)' test


            or



            grep -E '201806(19|2[01])' test


            The -E is needed to have grep understand | (alternation) in the expression (this alternation makes it an extended regular expression).




            You could also construct a regular expression from a brace expansion:



            set -- 19..21
            re=$( IFS='|'; printf '201806(%s)' "$*" )

            grep -E "$re" test


            This would first set the positional parameters, $1, $2 and $3, to the wanted numbers in the range. The variable re would then be set to 201806(%s) where printf would replace %s with these numbers delimited by |.



            The grep call would use 201806(19|20|21) as the regular expression.






            share|improve this answer























            • Or it could be done with a newline separated list of fixed strings maybe? i.e. printf '%sn' 20180619..21 | grep -Ff- test
              – steeldriver
              Jun 21 at 12:06











            • @steeldriver Yes, but I think you have to use /dev/stdin as the input file name, unless your grep interprets - as standard input.
              – Kusalananda
              Jun 21 at 12:08










            • It does - I didn't realize others didn't :(
              – steeldriver
              Jun 21 at 12:10












            up vote
            6
            down vote










            up vote
            6
            down vote









            Yes, grep only treats its first argument as a regular expression by default.



            This means that



            grep 1..9 file


            which expands to



            grep 1 2 3 4 5 6 7 8 9 file


            would invoke grep with 1 as the expression to match in the other operands, and that these other operands would be expected to be filenames.



            Your other command:



            grep 201806* test


            This would try to match 201806* as a filename globbing pattern. You have no files whose names start with 201806 in the current directory so the zsh shell fails to expand the pattern and gives you the error message no matches found.



            In other Bourne-like shells, if the pattern hadn't matched any filenames, it would have remained unexpanded and used as the regular expression with grep. The expression 201806*, when taken as a regular expression, matches 20180 followed by zero or more 6 characters, e.g. 2018066666.



            Instead, you may want to construct a regular expression to match your range:



            grep -E '201806(19|20|21)' test


            or



            grep -E '201806(19|2[01])' test


            The -E is needed to have grep understand | (alternation) in the expression (this alternation makes it an extended regular expression).




            You could also construct a regular expression from a brace expansion:



            set -- 19..21
            re=$( IFS='|'; printf '201806(%s)' "$*" )

            grep -E "$re" test


            This would first set the positional parameters, $1, $2 and $3, to the wanted numbers in the range. The variable re would then be set to 201806(%s) where printf would replace %s with these numbers delimited by |.



            The grep call would use 201806(19|20|21) as the regular expression.






            share|improve this answer















            Yes, grep only treats its first argument as a regular expression by default.



            This means that



            grep 1..9 file


            which expands to



            grep 1 2 3 4 5 6 7 8 9 file


            would invoke grep with 1 as the expression to match in the other operands, and that these other operands would be expected to be filenames.



            Your other command:



            grep 201806* test


            This would try to match 201806* as a filename globbing pattern. You have no files whose names start with 201806 in the current directory so the zsh shell fails to expand the pattern and gives you the error message no matches found.



            In other Bourne-like shells, if the pattern hadn't matched any filenames, it would have remained unexpanded and used as the regular expression with grep. The expression 201806*, when taken as a regular expression, matches 20180 followed by zero or more 6 characters, e.g. 2018066666.



            Instead, you may want to construct a regular expression to match your range:



            grep -E '201806(19|20|21)' test


            or



            grep -E '201806(19|2[01])' test


            The -E is needed to have grep understand | (alternation) in the expression (this alternation makes it an extended regular expression).




            You could also construct a regular expression from a brace expansion:



            set -- 19..21
            re=$( IFS='|'; printf '201806(%s)' "$*" )

            grep -E "$re" test


            This would first set the positional parameters, $1, $2 and $3, to the wanted numbers in the range. The variable re would then be set to 201806(%s) where printf would replace %s with these numbers delimited by |.



            The grep call would use 201806(19|20|21) as the regular expression.







            share|improve this answer















            share|improve this answer



            share|improve this answer








            edited Jun 22 at 14:19


























            answered Jun 21 at 10:14









            Kusalananda

            101k13199312




            101k13199312











            • Or it could be done with a newline separated list of fixed strings maybe? i.e. printf '%sn' 20180619..21 | grep -Ff- test
              – steeldriver
              Jun 21 at 12:06











            • @steeldriver Yes, but I think you have to use /dev/stdin as the input file name, unless your grep interprets - as standard input.
              – Kusalananda
              Jun 21 at 12:08










            • It does - I didn't realize others didn't :(
              – steeldriver
              Jun 21 at 12:10
















            • Or it could be done with a newline separated list of fixed strings maybe? i.e. printf '%sn' 20180619..21 | grep -Ff- test
              – steeldriver
              Jun 21 at 12:06











            • @steeldriver Yes, but I think you have to use /dev/stdin as the input file name, unless your grep interprets - as standard input.
              – Kusalananda
              Jun 21 at 12:08










            • It does - I didn't realize others didn't :(
              – steeldriver
              Jun 21 at 12:10















            Or it could be done with a newline separated list of fixed strings maybe? i.e. printf '%sn' 20180619..21 | grep -Ff- test
            – steeldriver
            Jun 21 at 12:06





            Or it could be done with a newline separated list of fixed strings maybe? i.e. printf '%sn' 20180619..21 | grep -Ff- test
            – steeldriver
            Jun 21 at 12:06













            @steeldriver Yes, but I think you have to use /dev/stdin as the input file name, unless your grep interprets - as standard input.
            – Kusalananda
            Jun 21 at 12:08




            @steeldriver Yes, but I think you have to use /dev/stdin as the input file name, unless your grep interprets - as standard input.
            – Kusalananda
            Jun 21 at 12:08












            It does - I didn't realize others didn't :(
            – steeldriver
            Jun 21 at 12:10




            It does - I didn't realize others didn't :(
            – steeldriver
            Jun 21 at 12:10










            up vote
            2
            down vote













            unquoted strings are interpreted by the shell before command is executed, in your case, the command you tried would be expanded to grep 20180619 20180620 20180621 test



            $ echo grep 20180619..21 test
            grep 20180619 20180620 20180621 test


            One workaround is to specify regular expression alternation:



            $ grep -E '201806(19|20|21)' test
            20180619:
            20180620:
            20180621:


            You can construct a numeric range with regular expressions, but it is not easy. See https://www.regular-expressions.info/numericranges.html for details





            Another option is to use awk



            $ awk -F: '$1>=20180619 && $1<=20180621' ip.txt
            20180619:
            20180620:
            20180621:


            Here, we split the line on : and then compare the first field $1 with range required






            share|improve this answer



























              up vote
              2
              down vote













              unquoted strings are interpreted by the shell before command is executed, in your case, the command you tried would be expanded to grep 20180619 20180620 20180621 test



              $ echo grep 20180619..21 test
              grep 20180619 20180620 20180621 test


              One workaround is to specify regular expression alternation:



              $ grep -E '201806(19|20|21)' test
              20180619:
              20180620:
              20180621:


              You can construct a numeric range with regular expressions, but it is not easy. See https://www.regular-expressions.info/numericranges.html for details





              Another option is to use awk



              $ awk -F: '$1>=20180619 && $1<=20180621' ip.txt
              20180619:
              20180620:
              20180621:


              Here, we split the line on : and then compare the first field $1 with range required






              share|improve this answer

























                up vote
                2
                down vote










                up vote
                2
                down vote









                unquoted strings are interpreted by the shell before command is executed, in your case, the command you tried would be expanded to grep 20180619 20180620 20180621 test



                $ echo grep 20180619..21 test
                grep 20180619 20180620 20180621 test


                One workaround is to specify regular expression alternation:



                $ grep -E '201806(19|20|21)' test
                20180619:
                20180620:
                20180621:


                You can construct a numeric range with regular expressions, but it is not easy. See https://www.regular-expressions.info/numericranges.html for details





                Another option is to use awk



                $ awk -F: '$1>=20180619 && $1<=20180621' ip.txt
                20180619:
                20180620:
                20180621:


                Here, we split the line on : and then compare the first field $1 with range required






                share|improve this answer















                unquoted strings are interpreted by the shell before command is executed, in your case, the command you tried would be expanded to grep 20180619 20180620 20180621 test



                $ echo grep 20180619..21 test
                grep 20180619 20180620 20180621 test


                One workaround is to specify regular expression alternation:



                $ grep -E '201806(19|20|21)' test
                20180619:
                20180620:
                20180621:


                You can construct a numeric range with regular expressions, but it is not easy. See https://www.regular-expressions.info/numericranges.html for details





                Another option is to use awk



                $ awk -F: '$1>=20180619 && $1<=20180621' ip.txt
                20180619:
                20180620:
                20180621:


                Here, we split the line on : and then compare the first field $1 with range required







                share|improve this answer















                share|improve this answer



                share|improve this answer








                edited Jun 21 at 10:20


























                answered Jun 21 at 10:14









                Sundeep

                6,9511826




                6,9511826




















                    up vote
                    1
                    down vote














                    1. POSIX shell (no bash) with utils:



                      seq 20180618 20180624 | grep -f - test



                    2. numgrep:



                      numgrep '/20180618..20180624/' < test






                    share|improve this answer



















                    • 2




                      (just to clear some possible confusion, note that neither seq nor numgrep are POSIX commands).
                      – Stéphane Chazelas
                      Jun 22 at 17:13














                    up vote
                    1
                    down vote














                    1. POSIX shell (no bash) with utils:



                      seq 20180618 20180624 | grep -f - test



                    2. numgrep:



                      numgrep '/20180618..20180624/' < test






                    share|improve this answer



















                    • 2




                      (just to clear some possible confusion, note that neither seq nor numgrep are POSIX commands).
                      – Stéphane Chazelas
                      Jun 22 at 17:13












                    up vote
                    1
                    down vote










                    up vote
                    1
                    down vote










                    1. POSIX shell (no bash) with utils:



                      seq 20180618 20180624 | grep -f - test



                    2. numgrep:



                      numgrep '/20180618..20180624/' < test






                    share|improve this answer
















                    1. POSIX shell (no bash) with utils:



                      seq 20180618 20180624 | grep -f - test



                    2. numgrep:



                      numgrep '/20180618..20180624/' < test







                    share|improve this answer















                    share|improve this answer



                    share|improve this answer








                    edited Jun 22 at 17:35


























                    answered Jun 22 at 17:08









                    agc

                    3,9991935




                    3,9991935







                    • 2




                      (just to clear some possible confusion, note that neither seq nor numgrep are POSIX commands).
                      – Stéphane Chazelas
                      Jun 22 at 17:13












                    • 2




                      (just to clear some possible confusion, note that neither seq nor numgrep are POSIX commands).
                      – Stéphane Chazelas
                      Jun 22 at 17:13







                    2




                    2




                    (just to clear some possible confusion, note that neither seq nor numgrep are POSIX commands).
                    – Stéphane Chazelas
                    Jun 22 at 17:13




                    (just to clear some possible confusion, note that neither seq nor numgrep are POSIX commands).
                    – Stéphane Chazelas
                    Jun 22 at 17:13












                     

                    draft saved


                    draft discarded


























                     


                    draft saved


                    draft discarded














                    StackExchange.ready(
                    function ()
                    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f451059%2fgrep-range-of-numbers-in-a-text-file%23new-answer', 'question_page');

                    );

                    Post as a guest













































































                    Popular posts from this blog

                    How to check contact read email or not when send email to Individual?

                    Bahrain

                    Postfix configuration issue with fips on centos 7; mailgun relay