print lines with specific number of specific char

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 a big text saving lots of file paths and their information



# just for demostration
/a/b/c/d/e
/a/b/c/d
/a/b/c
/a/b
/a
/b/c
/b
/c/d
/c
....


I want to show only those with specific number of specific char, for instance,



  1. with only one /

  2. with no more than two /

so that I extract only root folders or only to first-level subfolders.







share|improve this question




















  • Just because that looks like it could have been produced by find, gnu’s find has a maxdepth option that you may find useful.
    – Jeff Schaller
    Apr 11 at 18:24










  • @JeffSchaller I know find. but I'm working on text data, not real file structure. Your grep solution is perfect.
    – Lee
    Apr 11 at 19:00














up vote
0
down vote

favorite












I have a big text saving lots of file paths and their information



# just for demostration
/a/b/c/d/e
/a/b/c/d
/a/b/c
/a/b
/a
/b/c
/b
/c/d
/c
....


I want to show only those with specific number of specific char, for instance,



  1. with only one /

  2. with no more than two /

so that I extract only root folders or only to first-level subfolders.







share|improve this question




















  • Just because that looks like it could have been produced by find, gnu’s find has a maxdepth option that you may find useful.
    – Jeff Schaller
    Apr 11 at 18:24










  • @JeffSchaller I know find. but I'm working on text data, not real file structure. Your grep solution is perfect.
    – Lee
    Apr 11 at 19:00












up vote
0
down vote

favorite









up vote
0
down vote

favorite











I have a big text saving lots of file paths and their information



# just for demostration
/a/b/c/d/e
/a/b/c/d
/a/b/c
/a/b
/a
/b/c
/b
/c/d
/c
....


I want to show only those with specific number of specific char, for instance,



  1. with only one /

  2. with no more than two /

so that I extract only root folders or only to first-level subfolders.







share|improve this question












I have a big text saving lots of file paths and their information



# just for demostration
/a/b/c/d/e
/a/b/c/d
/a/b/c
/a/b
/a
/b/c
/b
/c/d
/c
....


I want to show only those with specific number of specific char, for instance,



  1. with only one /

  2. with no more than two /

so that I extract only root folders or only to first-level subfolders.









share|improve this question











share|improve this question




share|improve this question










asked Apr 11 at 17:59









Lee

7692718




7692718











  • Just because that looks like it could have been produced by find, gnu’s find has a maxdepth option that you may find useful.
    – Jeff Schaller
    Apr 11 at 18:24










  • @JeffSchaller I know find. but I'm working on text data, not real file structure. Your grep solution is perfect.
    – Lee
    Apr 11 at 19:00
















  • Just because that looks like it could have been produced by find, gnu’s find has a maxdepth option that you may find useful.
    – Jeff Schaller
    Apr 11 at 18:24










  • @JeffSchaller I know find. but I'm working on text data, not real file structure. Your grep solution is perfect.
    – Lee
    Apr 11 at 19:00















Just because that looks like it could have been produced by find, gnu’s find has a maxdepth option that you may find useful.
– Jeff Schaller
Apr 11 at 18:24




Just because that looks like it could have been produced by find, gnu’s find has a maxdepth option that you may find useful.
– Jeff Schaller
Apr 11 at 18:24












@JeffSchaller I know find. but I'm working on text data, not real file structure. Your grep solution is perfect.
– Lee
Apr 11 at 19:00




@JeffSchaller I know find. but I'm working on text data, not real file structure. Your grep solution is perfect.
– Lee
Apr 11 at 19:00










2 Answers
2






active

oldest

votes

















up vote
2
down vote



accepted










With an extended regular expression:



grep -E '^([^/]*/[^/]*)1,2$' input


which results in these matches:



/a/b
/a
/b/c
/b
/c/d
/c


The regex syntax says:




  • ^ - anchored to the beginning of the line


  • ( ... ) - group the following bits together


  • [^/]* - any non-forward-slash character, zero or more of them


  • / - a forward-slash


  • [^/]* - any non-forward-slash character, zero or more of them


  • 1,2 - one or two of those groups


  • $ - anchored to the end of the line





share|improve this answer



























    up vote
    5
    down vote













    Awk solution:



    -- with only one /:



    awk -v sep=1 'BEGIN FS=OFS="/"; sep += 1 NF == sep' file


    The output:



    /a
    /b
    /c



    -- with no more than two /:



    awk -v sep=2 'BEGIN FS=OFS="/"; sep += 1 NF <= sep' file


    The output:



    /a/b
    /a
    /b/c
    /b
    /c/d
    /c




    • sep - variable; stands for directory separator's count


    • FS and OFS - are field separator and output field separator respectively


    • NF - stands for total number of fields


    If you need to combine the above approaches into a single awk command:



    awk -v sep=1 'BEGIN FS=OFS="/"; sep += 1 (sep==2 && NF==sep) || (sep>2 && NF<=sep)' file





    share|improve this answer






















    • Thx. Good solutions! I chose the grep post as answer only because grep is easier to understand.
      – Lee
      Apr 11 at 18:32










    • Is the setting of OFS even necessary in this context?
      – steeldriver
      Apr 11 at 20:36










    • @steeldriver, in this narrow context - no. But it might be so in case if some field value would be changed for some purpose.
      – RomanPerekhrest
      Apr 11 at 20:41











    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%2f437103%2fprint-lines-with-specific-number-of-specific-char%23new-answer', 'question_page');

    );

    Post as a guest






























    2 Answers
    2






    active

    oldest

    votes








    2 Answers
    2






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes








    up vote
    2
    down vote



    accepted










    With an extended regular expression:



    grep -E '^([^/]*/[^/]*)1,2$' input


    which results in these matches:



    /a/b
    /a
    /b/c
    /b
    /c/d
    /c


    The regex syntax says:




    • ^ - anchored to the beginning of the line


    • ( ... ) - group the following bits together


    • [^/]* - any non-forward-slash character, zero or more of them


    • / - a forward-slash


    • [^/]* - any non-forward-slash character, zero or more of them


    • 1,2 - one or two of those groups


    • $ - anchored to the end of the line





    share|improve this answer
























      up vote
      2
      down vote



      accepted










      With an extended regular expression:



      grep -E '^([^/]*/[^/]*)1,2$' input


      which results in these matches:



      /a/b
      /a
      /b/c
      /b
      /c/d
      /c


      The regex syntax says:




      • ^ - anchored to the beginning of the line


      • ( ... ) - group the following bits together


      • [^/]* - any non-forward-slash character, zero or more of them


      • / - a forward-slash


      • [^/]* - any non-forward-slash character, zero or more of them


      • 1,2 - one or two of those groups


      • $ - anchored to the end of the line





      share|improve this answer






















        up vote
        2
        down vote



        accepted







        up vote
        2
        down vote



        accepted






        With an extended regular expression:



        grep -E '^([^/]*/[^/]*)1,2$' input


        which results in these matches:



        /a/b
        /a
        /b/c
        /b
        /c/d
        /c


        The regex syntax says:




        • ^ - anchored to the beginning of the line


        • ( ... ) - group the following bits together


        • [^/]* - any non-forward-slash character, zero or more of them


        • / - a forward-slash


        • [^/]* - any non-forward-slash character, zero or more of them


        • 1,2 - one or two of those groups


        • $ - anchored to the end of the line





        share|improve this answer












        With an extended regular expression:



        grep -E '^([^/]*/[^/]*)1,2$' input


        which results in these matches:



        /a/b
        /a
        /b/c
        /b
        /c/d
        /c


        The regex syntax says:




        • ^ - anchored to the beginning of the line


        • ( ... ) - group the following bits together


        • [^/]* - any non-forward-slash character, zero or more of them


        • / - a forward-slash


        • [^/]* - any non-forward-slash character, zero or more of them


        • 1,2 - one or two of those groups


        • $ - anchored to the end of the line






        share|improve this answer












        share|improve this answer



        share|improve this answer










        answered Apr 11 at 18:13









        Jeff Schaller

        31.1k846105




        31.1k846105






















            up vote
            5
            down vote













            Awk solution:



            -- with only one /:



            awk -v sep=1 'BEGIN FS=OFS="/"; sep += 1 NF == sep' file


            The output:



            /a
            /b
            /c



            -- with no more than two /:



            awk -v sep=2 'BEGIN FS=OFS="/"; sep += 1 NF <= sep' file


            The output:



            /a/b
            /a
            /b/c
            /b
            /c/d
            /c




            • sep - variable; stands for directory separator's count


            • FS and OFS - are field separator and output field separator respectively


            • NF - stands for total number of fields


            If you need to combine the above approaches into a single awk command:



            awk -v sep=1 'BEGIN FS=OFS="/"; sep += 1 (sep==2 && NF==sep) || (sep>2 && NF<=sep)' file





            share|improve this answer






















            • Thx. Good solutions! I chose the grep post as answer only because grep is easier to understand.
              – Lee
              Apr 11 at 18:32










            • Is the setting of OFS even necessary in this context?
              – steeldriver
              Apr 11 at 20:36










            • @steeldriver, in this narrow context - no. But it might be so in case if some field value would be changed for some purpose.
              – RomanPerekhrest
              Apr 11 at 20:41















            up vote
            5
            down vote













            Awk solution:



            -- with only one /:



            awk -v sep=1 'BEGIN FS=OFS="/"; sep += 1 NF == sep' file


            The output:



            /a
            /b
            /c



            -- with no more than two /:



            awk -v sep=2 'BEGIN FS=OFS="/"; sep += 1 NF <= sep' file


            The output:



            /a/b
            /a
            /b/c
            /b
            /c/d
            /c




            • sep - variable; stands for directory separator's count


            • FS and OFS - are field separator and output field separator respectively


            • NF - stands for total number of fields


            If you need to combine the above approaches into a single awk command:



            awk -v sep=1 'BEGIN FS=OFS="/"; sep += 1 (sep==2 && NF==sep) || (sep>2 && NF<=sep)' file





            share|improve this answer






















            • Thx. Good solutions! I chose the grep post as answer only because grep is easier to understand.
              – Lee
              Apr 11 at 18:32










            • Is the setting of OFS even necessary in this context?
              – steeldriver
              Apr 11 at 20:36










            • @steeldriver, in this narrow context - no. But it might be so in case if some field value would be changed for some purpose.
              – RomanPerekhrest
              Apr 11 at 20:41













            up vote
            5
            down vote










            up vote
            5
            down vote









            Awk solution:



            -- with only one /:



            awk -v sep=1 'BEGIN FS=OFS="/"; sep += 1 NF == sep' file


            The output:



            /a
            /b
            /c



            -- with no more than two /:



            awk -v sep=2 'BEGIN FS=OFS="/"; sep += 1 NF <= sep' file


            The output:



            /a/b
            /a
            /b/c
            /b
            /c/d
            /c




            • sep - variable; stands for directory separator's count


            • FS and OFS - are field separator and output field separator respectively


            • NF - stands for total number of fields


            If you need to combine the above approaches into a single awk command:



            awk -v sep=1 'BEGIN FS=OFS="/"; sep += 1 (sep==2 && NF==sep) || (sep>2 && NF<=sep)' file





            share|improve this answer














            Awk solution:



            -- with only one /:



            awk -v sep=1 'BEGIN FS=OFS="/"; sep += 1 NF == sep' file


            The output:



            /a
            /b
            /c



            -- with no more than two /:



            awk -v sep=2 'BEGIN FS=OFS="/"; sep += 1 NF <= sep' file


            The output:



            /a/b
            /a
            /b/c
            /b
            /c/d
            /c




            • sep - variable; stands for directory separator's count


            • FS and OFS - are field separator and output field separator respectively


            • NF - stands for total number of fields


            If you need to combine the above approaches into a single awk command:



            awk -v sep=1 'BEGIN FS=OFS="/"; sep += 1 (sep==2 && NF==sep) || (sep>2 && NF<=sep)' file






            share|improve this answer














            share|improve this answer



            share|improve this answer








            edited Apr 12 at 6:41

























            answered Apr 11 at 18:13









            RomanPerekhrest

            22.4k12144




            22.4k12144











            • Thx. Good solutions! I chose the grep post as answer only because grep is easier to understand.
              – Lee
              Apr 11 at 18:32










            • Is the setting of OFS even necessary in this context?
              – steeldriver
              Apr 11 at 20:36










            • @steeldriver, in this narrow context - no. But it might be so in case if some field value would be changed for some purpose.
              – RomanPerekhrest
              Apr 11 at 20:41

















            • Thx. Good solutions! I chose the grep post as answer only because grep is easier to understand.
              – Lee
              Apr 11 at 18:32










            • Is the setting of OFS even necessary in this context?
              – steeldriver
              Apr 11 at 20:36










            • @steeldriver, in this narrow context - no. But it might be so in case if some field value would be changed for some purpose.
              – RomanPerekhrest
              Apr 11 at 20:41
















            Thx. Good solutions! I chose the grep post as answer only because grep is easier to understand.
            – Lee
            Apr 11 at 18:32




            Thx. Good solutions! I chose the grep post as answer only because grep is easier to understand.
            – Lee
            Apr 11 at 18:32












            Is the setting of OFS even necessary in this context?
            – steeldriver
            Apr 11 at 20:36




            Is the setting of OFS even necessary in this context?
            – steeldriver
            Apr 11 at 20:36












            @steeldriver, in this narrow context - no. But it might be so in case if some field value would be changed for some purpose.
            – RomanPerekhrest
            Apr 11 at 20:41





            @steeldriver, in this narrow context - no. But it might be so in case if some field value would be changed for some purpose.
            – RomanPerekhrest
            Apr 11 at 20:41













             

            draft saved


            draft discarded


























             


            draft saved


            draft discarded














            StackExchange.ready(
            function ()
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f437103%2fprint-lines-with-specific-number-of-specific-char%23new-answer', 'question_page');

            );

            Post as a guest













































































            Popular posts from this blog

            Peggy Mitchell

            Palaiologos

            The Forum (Inglewood, California)