How to get the n-th line after a grepped one?












6















Consider the following text file



one 1
two 2
three 3
four 4
five 5
six 6
seven 7
eight 8


I would like to access to the second line after the one which matched four. This would be the line



six 6


The resulting line (so the one above) would then be piped for further processing (say, a | cut -d' ' -f2).



Is there a way to do this in bash and other typical utilities? (otherwise I will script it in Python)



EDIT: in my specific case the occurrence of four (to take that example) is guaranteed unique. But the answers show interesting extended cases when it is not.










share|improve this question




















  • 3





    Will there always only be one occurrence of what you are trying to match? Will it always be two lines after?

    – Nasir Riley
    2 days ago






  • 2





    Use awk? But if you're more familiar with Python that would be quicker.

    – MZB
    2 days ago











  • @NasirRiley: good point - I edited my question (four will be unique)

    – WoJ
    18 hours ago
















6















Consider the following text file



one 1
two 2
three 3
four 4
five 5
six 6
seven 7
eight 8


I would like to access to the second line after the one which matched four. This would be the line



six 6


The resulting line (so the one above) would then be piped for further processing (say, a | cut -d' ' -f2).



Is there a way to do this in bash and other typical utilities? (otherwise I will script it in Python)



EDIT: in my specific case the occurrence of four (to take that example) is guaranteed unique. But the answers show interesting extended cases when it is not.










share|improve this question




















  • 3





    Will there always only be one occurrence of what you are trying to match? Will it always be two lines after?

    – Nasir Riley
    2 days ago






  • 2





    Use awk? But if you're more familiar with Python that would be quicker.

    – MZB
    2 days ago











  • @NasirRiley: good point - I edited my question (four will be unique)

    – WoJ
    18 hours ago














6












6








6


2






Consider the following text file



one 1
two 2
three 3
four 4
five 5
six 6
seven 7
eight 8


I would like to access to the second line after the one which matched four. This would be the line



six 6


The resulting line (so the one above) would then be piped for further processing (say, a | cut -d' ' -f2).



Is there a way to do this in bash and other typical utilities? (otherwise I will script it in Python)



EDIT: in my specific case the occurrence of four (to take that example) is guaranteed unique. But the answers show interesting extended cases when it is not.










share|improve this question
















Consider the following text file



one 1
two 2
three 3
four 4
five 5
six 6
seven 7
eight 8


I would like to access to the second line after the one which matched four. This would be the line



six 6


The resulting line (so the one above) would then be piped for further processing (say, a | cut -d' ' -f2).



Is there a way to do this in bash and other typical utilities? (otherwise I will script it in Python)



EDIT: in my specific case the occurrence of four (to take that example) is guaranteed unique. But the answers show interesting extended cases when it is not.







linux command-line bash grep






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited 18 hours ago







WoJ

















asked 2 days ago









WoJWoJ

84932238




84932238








  • 3





    Will there always only be one occurrence of what you are trying to match? Will it always be two lines after?

    – Nasir Riley
    2 days ago






  • 2





    Use awk? But if you're more familiar with Python that would be quicker.

    – MZB
    2 days ago











  • @NasirRiley: good point - I edited my question (four will be unique)

    – WoJ
    18 hours ago














  • 3





    Will there always only be one occurrence of what you are trying to match? Will it always be two lines after?

    – Nasir Riley
    2 days ago






  • 2





    Use awk? But if you're more familiar with Python that would be quicker.

    – MZB
    2 days ago











  • @NasirRiley: good point - I edited my question (four will be unique)

    – WoJ
    18 hours ago








3




3





Will there always only be one occurrence of what you are trying to match? Will it always be two lines after?

– Nasir Riley
2 days ago





Will there always only be one occurrence of what you are trying to match? Will it always be two lines after?

– Nasir Riley
2 days ago




2




2





Use awk? But if you're more familiar with Python that would be quicker.

– MZB
2 days ago





Use awk? But if you're more familiar with Python that would be quicker.

– MZB
2 days ago













@NasirRiley: good point - I edited my question (four will be unique)

– WoJ
18 hours ago





@NasirRiley: good point - I edited my question (four will be unique)

– WoJ
18 hours ago










6 Answers
6






active

oldest

votes


















12














There is nothing wrong with the previous two answers, but I thought I would make you aware that finding the third line after a pattern can be done in a single sed call:



sed -n "/four/ { n; n; p }" SourceData.txt


Because a single program does the work, this is more efficient than running multiple filters. The above command outputs the third line after every instance of "four", except where this occurs again in one of the two lines following a match (the other solutions don't handle this case in the expected manner either); also, no output is generated if the pattern is in the last or second-last line of the file, which may or may not be what you want.



To match the first instance only:



sed -n "/four/ { n; n; p; q }" SourceData.txt


I add this solution because it is worth getting to know sed and, despite its rather off-putting syntax (regular expressions are bad enough!), it can often be extremely useful. This tutorial is a good introduction.






share|improve this answer
























  • "the other solutions don't handle this case in the expected manner either" – No longer true. :)

    – Kamil Maciorowski
    2 days ago











  • @KamilMaciorowski - I didn't think of awk: obviously another tool worth learning in detail. And there's a Grymoire tutorial, too!

    – AFH
    yesterday













  • The OP stated that four is guaranteed to appear just once. This makes your approach with q excellent because it won't parse the remaining input in vain. Nice.

    – Kamil Maciorowski
    17 hours ago











  • @KamilMaciorowski - I've just seen the edit. I thought of adding a note about the efficiency of adding q, but at the time I didn't know whether it answered the problem, so I didn't elaborate. The other answers (especially your own) should stand, since others with related problems may find them better solutions for their particular circumstances.

    – AFH
    16 hours ago



















8














Note: this answer was originally written before the OP clearly stated the pattern appears just once. It is designed not to miss any occurrence (unless near the end, so there's no "n-th line after") and I'm going to leave it this way. If you're sure there's only one occurrence or if you want only the first one to be found, you may consider some other solution that stops immediately and doesn't parse the whole input stream/file in vain.





This solution prints the current line iff there was a match two lines ago. It is slightly different from few other answers because it won't miss another match even if it occurs soon after the previous match.



awk -v delay=2 '{for (i=delay; i>=0; i--) t[i]=t[i-1]} /four/ {t[0]="m"} {if (t[delay]) print}'


Whenever there's a match, the information is stored in t[0]. With each line the t array is shifted (including shifting t[-1] to t[0] to reset the value of t[0]). The line is printed iff the array indicates there was a match two lines ago.



You can easily set a different delay (e.g. delay=7) or use another pattern (e.g. /sda[[:digit:]]/)






share|improve this answer


























  • This is the best solution, as it handles all occurrences of the pattern. However, it is quite long, might as well write a Python solution :D

    – justhalf
    yesterday








  • 1





    @justhalf One aspect though: awk is a standard POSIX tool, python is not.

    – Kamil Maciorowski
    yesterday



















5














You can use this expression (input.txt):



grep "four" -A 2 input.txt | tail -n 1


Output is:



six 6


The grep option "-A 2" states that two lines after the matched line are outputted.

And the tail option "-n 1" states that only the last 1 lines of this result are returned.






share|improve this answer



















  • 3





    Note that this only works if there's just a single match, or you're only interested in the last match.

    – Barmar
    yesterday





















2














For multiple occurences, and assumming that no lines start with --:



( grep -A 2  pattern data.txt; echo '--' ) | grep -E -B1 '^--' | grep -Ev '^--'


In slo-mo:





  • ( grep -A 2 pattern data.txt; echo '--' ) prints the pattern and the next two lines, and inserts a -- line between the groups. echo '--' makes sure that the last group is also followed by --.


  • grep -E -B1 '^--' print the separators and the lines just before (whoch are the ones we are looking for)


  • grep -Ev '^--' drops the separators, leaving only the lines we are looking for.






share|improve this answer
























  • if you use the -A, -B or -C option then grep automatically use -- to separate matches, no need to print it yourself

    – phuclv
    2 days ago











  • Doesn't add a '--' after the last., and it there is none, the rest of the pipeline won't get the last target (unless I add a tail -1 to every stage).

    – xenoid
    yesterday






  • 2





    I suggest searching for '^--$' as a way to reduce your failure mode still further.

    – Slartibartfast
    yesterday



















2














Looks like a good use case for ex, the POSIX-specified scriptable file editor.



Unlike sed and awk, ex is actually designed for file editing, not stream editing, and is capable of going backwards and forwards in a file. It's actually the non-visual form of the vi editor.



But the important aspect here is that ex is capable of chaining addresses. So referring to the line that's two lines after a particular text pattern is trivial.



Here is a command which prints all the lines that come two lines after lines containing four:



printf '%sn' 'g/four/+2p' | ex file.txt


I've written a lot of answers using ex on the Unix & Linux Stack Exchange; this one in particular has some additional explanations that may help.






share|improve this answer































    0














    You already got very good answers, which are easily the true go-to solutions for one-liners, but just in case you'd like or need to do it pure-bash only you might start from the following:



    { while read letters _ && [ "${letters}" != four ] ; do :; done ; read && read _ number _ && echo ${number} ; } < data.txt


    It only yields the first occurrence of "four".



    Here I used _ as the name for a placeholder variable, i.e. a variable that receives values to be discarded, and as an "added bonus" you have the | cut -f2 result already built into the script.



    Also please note that above script is just a proof-of-concept: it only works with the exampled input data.



    It could be enhanced by:




    • reading the entire (unsplit) line to match it against a regex via the [[ command (in place of [) along with its =~ operator, like in: while read line && ! [[ "${line}" =~ four ]] but beware the then additional complexity given by bash’s own escaping rules if the regex gets more complex than a simple "four"; also note the ! preceding the [[ to negate the test

    • joining the [ (or [[) command with the two read and the && echo ... together inside the while loop, to not stop after first match, like in:


    { while read letters _ ; do [ "${letters}" = four ] && read && read _ number _ && echo ${number} ; done ; } < data.txt


    Note also the change of the comparison operator. However beware of missing possibly adjacent matching lines. In order to address this possibility you’d need some kind of look-ahead or back-caching, for which you’d need some more advanced bash constructs.



    Lastly, of course you can rather output the entire unsplit line via read line && echo ${line} in place of read _ number _ && echo ${number}






    share|improve this answer










    New contributor




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





















    • So you’re assuming that the actual data is exactly like the sample data — the pattern to be searched for is a simple word that appears as a whole word, by itself, as the first word on a line.  But the question doesn’t say that; the sample data should be considered as just an example.  What if the line matching four actually says “I have fourteen cats.”?  What if the user actually wants to do this with a non-trivial regular expression (e.g., fox*ur)? … (Cont’d)

      – Scott
      5 hours ago











    • (Cont’d) …  What’s worse, the question clearly says that it wants to get the n-th (second) line after the line that matched — not the second word from that line.  Inasmuch as | cut -d' ' -f2 was also given as an example, baking it into your answer doesn’t earn you any points. … … … … … … … … … … … … … … Aside from that, this is a valid contribution to the discussion.  When you fix the above problems, consider showing two versions: one that finds the first match and stops, and another that finds all the matches.

      – Scott
      5 hours ago













    • @Scott: Well, my "script" is an example too, as much as the question’s information is an example itself - after all I did say "you could start with the following", and I suppose the script does look like just the proof-of-concept it indeed is. But I should make that clearer, agreed. Then, should I provide that much more functionality than explicitly requested ? In order to implement those additional features the script might easily become way more complex than it already is. Wouldn’t that risk to be an overkill ? I think I’d rather wait for explicit inquiries, if and when any (cont'd)

      – LL3
      5 hours ago











    • (cont'd) Wrt the “doing away the cut -f2 part”, it was certainly not for gaining points (nor is my entire contribution as a whole, considering that it is in general quite inferior (ie more complicated) to the other solutions), rather it just cost nothing to do it rather than not, considering that the question mentioned it as a likely subsequent processing of the input data. I contribute with a HTH mindset, I can do without an upvote and am happy with just a “nice, thank you”.

      – LL3
      5 hours ago











    Your Answer








    StackExchange.ready(function() {
    var channelOptions = {
    tags: "".split(" "),
    id: "3"
    };
    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: true,
    noModals: true,
    showLowRepImageUploadWarning: true,
    reputationToPostImages: 10,
    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%2fsuperuser.com%2fquestions%2f1414661%2fhow-to-get-the-n-th-line-after-a-grepped-one%23new-answer', 'question_page');
    }
    );

    Post as a guest















    Required, but never shown

























    6 Answers
    6






    active

    oldest

    votes








    6 Answers
    6






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes









    12














    There is nothing wrong with the previous two answers, but I thought I would make you aware that finding the third line after a pattern can be done in a single sed call:



    sed -n "/four/ { n; n; p }" SourceData.txt


    Because a single program does the work, this is more efficient than running multiple filters. The above command outputs the third line after every instance of "four", except where this occurs again in one of the two lines following a match (the other solutions don't handle this case in the expected manner either); also, no output is generated if the pattern is in the last or second-last line of the file, which may or may not be what you want.



    To match the first instance only:



    sed -n "/four/ { n; n; p; q }" SourceData.txt


    I add this solution because it is worth getting to know sed and, despite its rather off-putting syntax (regular expressions are bad enough!), it can often be extremely useful. This tutorial is a good introduction.






    share|improve this answer
























    • "the other solutions don't handle this case in the expected manner either" – No longer true. :)

      – Kamil Maciorowski
      2 days ago











    • @KamilMaciorowski - I didn't think of awk: obviously another tool worth learning in detail. And there's a Grymoire tutorial, too!

      – AFH
      yesterday













    • The OP stated that four is guaranteed to appear just once. This makes your approach with q excellent because it won't parse the remaining input in vain. Nice.

      – Kamil Maciorowski
      17 hours ago











    • @KamilMaciorowski - I've just seen the edit. I thought of adding a note about the efficiency of adding q, but at the time I didn't know whether it answered the problem, so I didn't elaborate. The other answers (especially your own) should stand, since others with related problems may find them better solutions for their particular circumstances.

      – AFH
      16 hours ago
















    12














    There is nothing wrong with the previous two answers, but I thought I would make you aware that finding the third line after a pattern can be done in a single sed call:



    sed -n "/four/ { n; n; p }" SourceData.txt


    Because a single program does the work, this is more efficient than running multiple filters. The above command outputs the third line after every instance of "four", except where this occurs again in one of the two lines following a match (the other solutions don't handle this case in the expected manner either); also, no output is generated if the pattern is in the last or second-last line of the file, which may or may not be what you want.



    To match the first instance only:



    sed -n "/four/ { n; n; p; q }" SourceData.txt


    I add this solution because it is worth getting to know sed and, despite its rather off-putting syntax (regular expressions are bad enough!), it can often be extremely useful. This tutorial is a good introduction.






    share|improve this answer
























    • "the other solutions don't handle this case in the expected manner either" – No longer true. :)

      – Kamil Maciorowski
      2 days ago











    • @KamilMaciorowski - I didn't think of awk: obviously another tool worth learning in detail. And there's a Grymoire tutorial, too!

      – AFH
      yesterday













    • The OP stated that four is guaranteed to appear just once. This makes your approach with q excellent because it won't parse the remaining input in vain. Nice.

      – Kamil Maciorowski
      17 hours ago











    • @KamilMaciorowski - I've just seen the edit. I thought of adding a note about the efficiency of adding q, but at the time I didn't know whether it answered the problem, so I didn't elaborate. The other answers (especially your own) should stand, since others with related problems may find them better solutions for their particular circumstances.

      – AFH
      16 hours ago














    12












    12








    12







    There is nothing wrong with the previous two answers, but I thought I would make you aware that finding the third line after a pattern can be done in a single sed call:



    sed -n "/four/ { n; n; p }" SourceData.txt


    Because a single program does the work, this is more efficient than running multiple filters. The above command outputs the third line after every instance of "four", except where this occurs again in one of the two lines following a match (the other solutions don't handle this case in the expected manner either); also, no output is generated if the pattern is in the last or second-last line of the file, which may or may not be what you want.



    To match the first instance only:



    sed -n "/four/ { n; n; p; q }" SourceData.txt


    I add this solution because it is worth getting to know sed and, despite its rather off-putting syntax (regular expressions are bad enough!), it can often be extremely useful. This tutorial is a good introduction.






    share|improve this answer













    There is nothing wrong with the previous two answers, but I thought I would make you aware that finding the third line after a pattern can be done in a single sed call:



    sed -n "/four/ { n; n; p }" SourceData.txt


    Because a single program does the work, this is more efficient than running multiple filters. The above command outputs the third line after every instance of "four", except where this occurs again in one of the two lines following a match (the other solutions don't handle this case in the expected manner either); also, no output is generated if the pattern is in the last or second-last line of the file, which may or may not be what you want.



    To match the first instance only:



    sed -n "/four/ { n; n; p; q }" SourceData.txt


    I add this solution because it is worth getting to know sed and, despite its rather off-putting syntax (regular expressions are bad enough!), it can often be extremely useful. This tutorial is a good introduction.







    share|improve this answer












    share|improve this answer



    share|improve this answer










    answered 2 days ago









    AFHAFH

    14.5k31939




    14.5k31939













    • "the other solutions don't handle this case in the expected manner either" – No longer true. :)

      – Kamil Maciorowski
      2 days ago











    • @KamilMaciorowski - I didn't think of awk: obviously another tool worth learning in detail. And there's a Grymoire tutorial, too!

      – AFH
      yesterday













    • The OP stated that four is guaranteed to appear just once. This makes your approach with q excellent because it won't parse the remaining input in vain. Nice.

      – Kamil Maciorowski
      17 hours ago











    • @KamilMaciorowski - I've just seen the edit. I thought of adding a note about the efficiency of adding q, but at the time I didn't know whether it answered the problem, so I didn't elaborate. The other answers (especially your own) should stand, since others with related problems may find them better solutions for their particular circumstances.

      – AFH
      16 hours ago



















    • "the other solutions don't handle this case in the expected manner either" – No longer true. :)

      – Kamil Maciorowski
      2 days ago











    • @KamilMaciorowski - I didn't think of awk: obviously another tool worth learning in detail. And there's a Grymoire tutorial, too!

      – AFH
      yesterday













    • The OP stated that four is guaranteed to appear just once. This makes your approach with q excellent because it won't parse the remaining input in vain. Nice.

      – Kamil Maciorowski
      17 hours ago











    • @KamilMaciorowski - I've just seen the edit. I thought of adding a note about the efficiency of adding q, but at the time I didn't know whether it answered the problem, so I didn't elaborate. The other answers (especially your own) should stand, since others with related problems may find them better solutions for their particular circumstances.

      – AFH
      16 hours ago

















    "the other solutions don't handle this case in the expected manner either" – No longer true. :)

    – Kamil Maciorowski
    2 days ago





    "the other solutions don't handle this case in the expected manner either" – No longer true. :)

    – Kamil Maciorowski
    2 days ago













    @KamilMaciorowski - I didn't think of awk: obviously another tool worth learning in detail. And there's a Grymoire tutorial, too!

    – AFH
    yesterday







    @KamilMaciorowski - I didn't think of awk: obviously another tool worth learning in detail. And there's a Grymoire tutorial, too!

    – AFH
    yesterday















    The OP stated that four is guaranteed to appear just once. This makes your approach with q excellent because it won't parse the remaining input in vain. Nice.

    – Kamil Maciorowski
    17 hours ago





    The OP stated that four is guaranteed to appear just once. This makes your approach with q excellent because it won't parse the remaining input in vain. Nice.

    – Kamil Maciorowski
    17 hours ago













    @KamilMaciorowski - I've just seen the edit. I thought of adding a note about the efficiency of adding q, but at the time I didn't know whether it answered the problem, so I didn't elaborate. The other answers (especially your own) should stand, since others with related problems may find them better solutions for their particular circumstances.

    – AFH
    16 hours ago





    @KamilMaciorowski - I've just seen the edit. I thought of adding a note about the efficiency of adding q, but at the time I didn't know whether it answered the problem, so I didn't elaborate. The other answers (especially your own) should stand, since others with related problems may find them better solutions for their particular circumstances.

    – AFH
    16 hours ago













    8














    Note: this answer was originally written before the OP clearly stated the pattern appears just once. It is designed not to miss any occurrence (unless near the end, so there's no "n-th line after") and I'm going to leave it this way. If you're sure there's only one occurrence or if you want only the first one to be found, you may consider some other solution that stops immediately and doesn't parse the whole input stream/file in vain.





    This solution prints the current line iff there was a match two lines ago. It is slightly different from few other answers because it won't miss another match even if it occurs soon after the previous match.



    awk -v delay=2 '{for (i=delay; i>=0; i--) t[i]=t[i-1]} /four/ {t[0]="m"} {if (t[delay]) print}'


    Whenever there's a match, the information is stored in t[0]. With each line the t array is shifted (including shifting t[-1] to t[0] to reset the value of t[0]). The line is printed iff the array indicates there was a match two lines ago.



    You can easily set a different delay (e.g. delay=7) or use another pattern (e.g. /sda[[:digit:]]/)






    share|improve this answer


























    • This is the best solution, as it handles all occurrences of the pattern. However, it is quite long, might as well write a Python solution :D

      – justhalf
      yesterday








    • 1





      @justhalf One aspect though: awk is a standard POSIX tool, python is not.

      – Kamil Maciorowski
      yesterday
















    8














    Note: this answer was originally written before the OP clearly stated the pattern appears just once. It is designed not to miss any occurrence (unless near the end, so there's no "n-th line after") and I'm going to leave it this way. If you're sure there's only one occurrence or if you want only the first one to be found, you may consider some other solution that stops immediately and doesn't parse the whole input stream/file in vain.





    This solution prints the current line iff there was a match two lines ago. It is slightly different from few other answers because it won't miss another match even if it occurs soon after the previous match.



    awk -v delay=2 '{for (i=delay; i>=0; i--) t[i]=t[i-1]} /four/ {t[0]="m"} {if (t[delay]) print}'


    Whenever there's a match, the information is stored in t[0]. With each line the t array is shifted (including shifting t[-1] to t[0] to reset the value of t[0]). The line is printed iff the array indicates there was a match two lines ago.



    You can easily set a different delay (e.g. delay=7) or use another pattern (e.g. /sda[[:digit:]]/)






    share|improve this answer


























    • This is the best solution, as it handles all occurrences of the pattern. However, it is quite long, might as well write a Python solution :D

      – justhalf
      yesterday








    • 1





      @justhalf One aspect though: awk is a standard POSIX tool, python is not.

      – Kamil Maciorowski
      yesterday














    8












    8








    8







    Note: this answer was originally written before the OP clearly stated the pattern appears just once. It is designed not to miss any occurrence (unless near the end, so there's no "n-th line after") and I'm going to leave it this way. If you're sure there's only one occurrence or if you want only the first one to be found, you may consider some other solution that stops immediately and doesn't parse the whole input stream/file in vain.





    This solution prints the current line iff there was a match two lines ago. It is slightly different from few other answers because it won't miss another match even if it occurs soon after the previous match.



    awk -v delay=2 '{for (i=delay; i>=0; i--) t[i]=t[i-1]} /four/ {t[0]="m"} {if (t[delay]) print}'


    Whenever there's a match, the information is stored in t[0]. With each line the t array is shifted (including shifting t[-1] to t[0] to reset the value of t[0]). The line is printed iff the array indicates there was a match two lines ago.



    You can easily set a different delay (e.g. delay=7) or use another pattern (e.g. /sda[[:digit:]]/)






    share|improve this answer















    Note: this answer was originally written before the OP clearly stated the pattern appears just once. It is designed not to miss any occurrence (unless near the end, so there's no "n-th line after") and I'm going to leave it this way. If you're sure there's only one occurrence or if you want only the first one to be found, you may consider some other solution that stops immediately and doesn't parse the whole input stream/file in vain.





    This solution prints the current line iff there was a match two lines ago. It is slightly different from few other answers because it won't miss another match even if it occurs soon after the previous match.



    awk -v delay=2 '{for (i=delay; i>=0; i--) t[i]=t[i-1]} /four/ {t[0]="m"} {if (t[delay]) print}'


    Whenever there's a match, the information is stored in t[0]. With each line the t array is shifted (including shifting t[-1] to t[0] to reset the value of t[0]). The line is printed iff the array indicates there was a match two lines ago.



    You can easily set a different delay (e.g. delay=7) or use another pattern (e.g. /sda[[:digit:]]/)







    share|improve this answer














    share|improve this answer



    share|improve this answer








    edited 17 hours ago

























    answered 2 days ago









    Kamil MaciorowskiKamil Maciorowski

    28.4k156186




    28.4k156186













    • This is the best solution, as it handles all occurrences of the pattern. However, it is quite long, might as well write a Python solution :D

      – justhalf
      yesterday








    • 1





      @justhalf One aspect though: awk is a standard POSIX tool, python is not.

      – Kamil Maciorowski
      yesterday



















    • This is the best solution, as it handles all occurrences of the pattern. However, it is quite long, might as well write a Python solution :D

      – justhalf
      yesterday








    • 1





      @justhalf One aspect though: awk is a standard POSIX tool, python is not.

      – Kamil Maciorowski
      yesterday

















    This is the best solution, as it handles all occurrences of the pattern. However, it is quite long, might as well write a Python solution :D

    – justhalf
    yesterday







    This is the best solution, as it handles all occurrences of the pattern. However, it is quite long, might as well write a Python solution :D

    – justhalf
    yesterday






    1




    1





    @justhalf One aspect though: awk is a standard POSIX tool, python is not.

    – Kamil Maciorowski
    yesterday





    @justhalf One aspect though: awk is a standard POSIX tool, python is not.

    – Kamil Maciorowski
    yesterday











    5














    You can use this expression (input.txt):



    grep "four" -A 2 input.txt | tail -n 1


    Output is:



    six 6


    The grep option "-A 2" states that two lines after the matched line are outputted.

    And the tail option "-n 1" states that only the last 1 lines of this result are returned.






    share|improve this answer



















    • 3





      Note that this only works if there's just a single match, or you're only interested in the last match.

      – Barmar
      yesterday


















    5














    You can use this expression (input.txt):



    grep "four" -A 2 input.txt | tail -n 1


    Output is:



    six 6


    The grep option "-A 2" states that two lines after the matched line are outputted.

    And the tail option "-n 1" states that only the last 1 lines of this result are returned.






    share|improve this answer



















    • 3





      Note that this only works if there's just a single match, or you're only interested in the last match.

      – Barmar
      yesterday
















    5












    5








    5







    You can use this expression (input.txt):



    grep "four" -A 2 input.txt | tail -n 1


    Output is:



    six 6


    The grep option "-A 2" states that two lines after the matched line are outputted.

    And the tail option "-n 1" states that only the last 1 lines of this result are returned.






    share|improve this answer













    You can use this expression (input.txt):



    grep "four" -A 2 input.txt | tail -n 1


    Output is:



    six 6


    The grep option "-A 2" states that two lines after the matched line are outputted.

    And the tail option "-n 1" states that only the last 1 lines of this result are returned.







    share|improve this answer












    share|improve this answer



    share|improve this answer










    answered 2 days ago









    zx485zx485

    1,0711913




    1,0711913








    • 3





      Note that this only works if there's just a single match, or you're only interested in the last match.

      – Barmar
      yesterday
















    • 3





      Note that this only works if there's just a single match, or you're only interested in the last match.

      – Barmar
      yesterday










    3




    3





    Note that this only works if there's just a single match, or you're only interested in the last match.

    – Barmar
    yesterday







    Note that this only works if there's just a single match, or you're only interested in the last match.

    – Barmar
    yesterday













    2














    For multiple occurences, and assumming that no lines start with --:



    ( grep -A 2  pattern data.txt; echo '--' ) | grep -E -B1 '^--' | grep -Ev '^--'


    In slo-mo:





    • ( grep -A 2 pattern data.txt; echo '--' ) prints the pattern and the next two lines, and inserts a -- line between the groups. echo '--' makes sure that the last group is also followed by --.


    • grep -E -B1 '^--' print the separators and the lines just before (whoch are the ones we are looking for)


    • grep -Ev '^--' drops the separators, leaving only the lines we are looking for.






    share|improve this answer
























    • if you use the -A, -B or -C option then grep automatically use -- to separate matches, no need to print it yourself

      – phuclv
      2 days ago











    • Doesn't add a '--' after the last., and it there is none, the rest of the pipeline won't get the last target (unless I add a tail -1 to every stage).

      – xenoid
      yesterday






    • 2





      I suggest searching for '^--$' as a way to reduce your failure mode still further.

      – Slartibartfast
      yesterday
















    2














    For multiple occurences, and assumming that no lines start with --:



    ( grep -A 2  pattern data.txt; echo '--' ) | grep -E -B1 '^--' | grep -Ev '^--'


    In slo-mo:





    • ( grep -A 2 pattern data.txt; echo '--' ) prints the pattern and the next two lines, and inserts a -- line between the groups. echo '--' makes sure that the last group is also followed by --.


    • grep -E -B1 '^--' print the separators and the lines just before (whoch are the ones we are looking for)


    • grep -Ev '^--' drops the separators, leaving only the lines we are looking for.






    share|improve this answer
























    • if you use the -A, -B or -C option then grep automatically use -- to separate matches, no need to print it yourself

      – phuclv
      2 days ago











    • Doesn't add a '--' after the last., and it there is none, the rest of the pipeline won't get the last target (unless I add a tail -1 to every stage).

      – xenoid
      yesterday






    • 2





      I suggest searching for '^--$' as a way to reduce your failure mode still further.

      – Slartibartfast
      yesterday














    2












    2








    2







    For multiple occurences, and assumming that no lines start with --:



    ( grep -A 2  pattern data.txt; echo '--' ) | grep -E -B1 '^--' | grep -Ev '^--'


    In slo-mo:





    • ( grep -A 2 pattern data.txt; echo '--' ) prints the pattern and the next two lines, and inserts a -- line between the groups. echo '--' makes sure that the last group is also followed by --.


    • grep -E -B1 '^--' print the separators and the lines just before (whoch are the ones we are looking for)


    • grep -Ev '^--' drops the separators, leaving only the lines we are looking for.






    share|improve this answer













    For multiple occurences, and assumming that no lines start with --:



    ( grep -A 2  pattern data.txt; echo '--' ) | grep -E -B1 '^--' | grep -Ev '^--'


    In slo-mo:





    • ( grep -A 2 pattern data.txt; echo '--' ) prints the pattern and the next two lines, and inserts a -- line between the groups. echo '--' makes sure that the last group is also followed by --.


    • grep -E -B1 '^--' print the separators and the lines just before (whoch are the ones we are looking for)


    • grep -Ev '^--' drops the separators, leaving only the lines we are looking for.







    share|improve this answer












    share|improve this answer



    share|improve this answer










    answered 2 days ago









    xenoidxenoid

    3,8593719




    3,8593719













    • if you use the -A, -B or -C option then grep automatically use -- to separate matches, no need to print it yourself

      – phuclv
      2 days ago











    • Doesn't add a '--' after the last., and it there is none, the rest of the pipeline won't get the last target (unless I add a tail -1 to every stage).

      – xenoid
      yesterday






    • 2





      I suggest searching for '^--$' as a way to reduce your failure mode still further.

      – Slartibartfast
      yesterday



















    • if you use the -A, -B or -C option then grep automatically use -- to separate matches, no need to print it yourself

      – phuclv
      2 days ago











    • Doesn't add a '--' after the last., and it there is none, the rest of the pipeline won't get the last target (unless I add a tail -1 to every stage).

      – xenoid
      yesterday






    • 2





      I suggest searching for '^--$' as a way to reduce your failure mode still further.

      – Slartibartfast
      yesterday

















    if you use the -A, -B or -C option then grep automatically use -- to separate matches, no need to print it yourself

    – phuclv
    2 days ago





    if you use the -A, -B or -C option then grep automatically use -- to separate matches, no need to print it yourself

    – phuclv
    2 days ago













    Doesn't add a '--' after the last., and it there is none, the rest of the pipeline won't get the last target (unless I add a tail -1 to every stage).

    – xenoid
    yesterday





    Doesn't add a '--' after the last., and it there is none, the rest of the pipeline won't get the last target (unless I add a tail -1 to every stage).

    – xenoid
    yesterday




    2




    2





    I suggest searching for '^--$' as a way to reduce your failure mode still further.

    – Slartibartfast
    yesterday





    I suggest searching for '^--$' as a way to reduce your failure mode still further.

    – Slartibartfast
    yesterday











    2














    Looks like a good use case for ex, the POSIX-specified scriptable file editor.



    Unlike sed and awk, ex is actually designed for file editing, not stream editing, and is capable of going backwards and forwards in a file. It's actually the non-visual form of the vi editor.



    But the important aspect here is that ex is capable of chaining addresses. So referring to the line that's two lines after a particular text pattern is trivial.



    Here is a command which prints all the lines that come two lines after lines containing four:



    printf '%sn' 'g/four/+2p' | ex file.txt


    I've written a lot of answers using ex on the Unix & Linux Stack Exchange; this one in particular has some additional explanations that may help.






    share|improve this answer




























      2














      Looks like a good use case for ex, the POSIX-specified scriptable file editor.



      Unlike sed and awk, ex is actually designed for file editing, not stream editing, and is capable of going backwards and forwards in a file. It's actually the non-visual form of the vi editor.



      But the important aspect here is that ex is capable of chaining addresses. So referring to the line that's two lines after a particular text pattern is trivial.



      Here is a command which prints all the lines that come two lines after lines containing four:



      printf '%sn' 'g/four/+2p' | ex file.txt


      I've written a lot of answers using ex on the Unix & Linux Stack Exchange; this one in particular has some additional explanations that may help.






      share|improve this answer


























        2












        2








        2







        Looks like a good use case for ex, the POSIX-specified scriptable file editor.



        Unlike sed and awk, ex is actually designed for file editing, not stream editing, and is capable of going backwards and forwards in a file. It's actually the non-visual form of the vi editor.



        But the important aspect here is that ex is capable of chaining addresses. So referring to the line that's two lines after a particular text pattern is trivial.



        Here is a command which prints all the lines that come two lines after lines containing four:



        printf '%sn' 'g/four/+2p' | ex file.txt


        I've written a lot of answers using ex on the Unix & Linux Stack Exchange; this one in particular has some additional explanations that may help.






        share|improve this answer













        Looks like a good use case for ex, the POSIX-specified scriptable file editor.



        Unlike sed and awk, ex is actually designed for file editing, not stream editing, and is capable of going backwards and forwards in a file. It's actually the non-visual form of the vi editor.



        But the important aspect here is that ex is capable of chaining addresses. So referring to the line that's two lines after a particular text pattern is trivial.



        Here is a command which prints all the lines that come two lines after lines containing four:



        printf '%sn' 'g/four/+2p' | ex file.txt


        I've written a lot of answers using ex on the Unix & Linux Stack Exchange; this one in particular has some additional explanations that may help.







        share|improve this answer












        share|improve this answer



        share|improve this answer










        answered 19 hours ago









        WildcardWildcard

        293517




        293517























            0














            You already got very good answers, which are easily the true go-to solutions for one-liners, but just in case you'd like or need to do it pure-bash only you might start from the following:



            { while read letters _ && [ "${letters}" != four ] ; do :; done ; read && read _ number _ && echo ${number} ; } < data.txt


            It only yields the first occurrence of "four".



            Here I used _ as the name for a placeholder variable, i.e. a variable that receives values to be discarded, and as an "added bonus" you have the | cut -f2 result already built into the script.



            Also please note that above script is just a proof-of-concept: it only works with the exampled input data.



            It could be enhanced by:




            • reading the entire (unsplit) line to match it against a regex via the [[ command (in place of [) along with its =~ operator, like in: while read line && ! [[ "${line}" =~ four ]] but beware the then additional complexity given by bash’s own escaping rules if the regex gets more complex than a simple "four"; also note the ! preceding the [[ to negate the test

            • joining the [ (or [[) command with the two read and the && echo ... together inside the while loop, to not stop after first match, like in:


            { while read letters _ ; do [ "${letters}" = four ] && read && read _ number _ && echo ${number} ; done ; } < data.txt


            Note also the change of the comparison operator. However beware of missing possibly adjacent matching lines. In order to address this possibility you’d need some kind of look-ahead or back-caching, for which you’d need some more advanced bash constructs.



            Lastly, of course you can rather output the entire unsplit line via read line && echo ${line} in place of read _ number _ && echo ${number}






            share|improve this answer










            New contributor




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





















            • So you’re assuming that the actual data is exactly like the sample data — the pattern to be searched for is a simple word that appears as a whole word, by itself, as the first word on a line.  But the question doesn’t say that; the sample data should be considered as just an example.  What if the line matching four actually says “I have fourteen cats.”?  What if the user actually wants to do this with a non-trivial regular expression (e.g., fox*ur)? … (Cont’d)

              – Scott
              5 hours ago











            • (Cont’d) …  What’s worse, the question clearly says that it wants to get the n-th (second) line after the line that matched — not the second word from that line.  Inasmuch as | cut -d' ' -f2 was also given as an example, baking it into your answer doesn’t earn you any points. … … … … … … … … … … … … … … Aside from that, this is a valid contribution to the discussion.  When you fix the above problems, consider showing two versions: one that finds the first match and stops, and another that finds all the matches.

              – Scott
              5 hours ago













            • @Scott: Well, my "script" is an example too, as much as the question’s information is an example itself - after all I did say "you could start with the following", and I suppose the script does look like just the proof-of-concept it indeed is. But I should make that clearer, agreed. Then, should I provide that much more functionality than explicitly requested ? In order to implement those additional features the script might easily become way more complex than it already is. Wouldn’t that risk to be an overkill ? I think I’d rather wait for explicit inquiries, if and when any (cont'd)

              – LL3
              5 hours ago











            • (cont'd) Wrt the “doing away the cut -f2 part”, it was certainly not for gaining points (nor is my entire contribution as a whole, considering that it is in general quite inferior (ie more complicated) to the other solutions), rather it just cost nothing to do it rather than not, considering that the question mentioned it as a likely subsequent processing of the input data. I contribute with a HTH mindset, I can do without an upvote and am happy with just a “nice, thank you”.

              – LL3
              5 hours ago
















            0














            You already got very good answers, which are easily the true go-to solutions for one-liners, but just in case you'd like or need to do it pure-bash only you might start from the following:



            { while read letters _ && [ "${letters}" != four ] ; do :; done ; read && read _ number _ && echo ${number} ; } < data.txt


            It only yields the first occurrence of "four".



            Here I used _ as the name for a placeholder variable, i.e. a variable that receives values to be discarded, and as an "added bonus" you have the | cut -f2 result already built into the script.



            Also please note that above script is just a proof-of-concept: it only works with the exampled input data.



            It could be enhanced by:




            • reading the entire (unsplit) line to match it against a regex via the [[ command (in place of [) along with its =~ operator, like in: while read line && ! [[ "${line}" =~ four ]] but beware the then additional complexity given by bash’s own escaping rules if the regex gets more complex than a simple "four"; also note the ! preceding the [[ to negate the test

            • joining the [ (or [[) command with the two read and the && echo ... together inside the while loop, to not stop after first match, like in:


            { while read letters _ ; do [ "${letters}" = four ] && read && read _ number _ && echo ${number} ; done ; } < data.txt


            Note also the change of the comparison operator. However beware of missing possibly adjacent matching lines. In order to address this possibility you’d need some kind of look-ahead or back-caching, for which you’d need some more advanced bash constructs.



            Lastly, of course you can rather output the entire unsplit line via read line && echo ${line} in place of read _ number _ && echo ${number}






            share|improve this answer










            New contributor




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





















            • So you’re assuming that the actual data is exactly like the sample data — the pattern to be searched for is a simple word that appears as a whole word, by itself, as the first word on a line.  But the question doesn’t say that; the sample data should be considered as just an example.  What if the line matching four actually says “I have fourteen cats.”?  What if the user actually wants to do this with a non-trivial regular expression (e.g., fox*ur)? … (Cont’d)

              – Scott
              5 hours ago











            • (Cont’d) …  What’s worse, the question clearly says that it wants to get the n-th (second) line after the line that matched — not the second word from that line.  Inasmuch as | cut -d' ' -f2 was also given as an example, baking it into your answer doesn’t earn you any points. … … … … … … … … … … … … … … Aside from that, this is a valid contribution to the discussion.  When you fix the above problems, consider showing two versions: one that finds the first match and stops, and another that finds all the matches.

              – Scott
              5 hours ago













            • @Scott: Well, my "script" is an example too, as much as the question’s information is an example itself - after all I did say "you could start with the following", and I suppose the script does look like just the proof-of-concept it indeed is. But I should make that clearer, agreed. Then, should I provide that much more functionality than explicitly requested ? In order to implement those additional features the script might easily become way more complex than it already is. Wouldn’t that risk to be an overkill ? I think I’d rather wait for explicit inquiries, if and when any (cont'd)

              – LL3
              5 hours ago











            • (cont'd) Wrt the “doing away the cut -f2 part”, it was certainly not for gaining points (nor is my entire contribution as a whole, considering that it is in general quite inferior (ie more complicated) to the other solutions), rather it just cost nothing to do it rather than not, considering that the question mentioned it as a likely subsequent processing of the input data. I contribute with a HTH mindset, I can do without an upvote and am happy with just a “nice, thank you”.

              – LL3
              5 hours ago














            0












            0








            0







            You already got very good answers, which are easily the true go-to solutions for one-liners, but just in case you'd like or need to do it pure-bash only you might start from the following:



            { while read letters _ && [ "${letters}" != four ] ; do :; done ; read && read _ number _ && echo ${number} ; } < data.txt


            It only yields the first occurrence of "four".



            Here I used _ as the name for a placeholder variable, i.e. a variable that receives values to be discarded, and as an "added bonus" you have the | cut -f2 result already built into the script.



            Also please note that above script is just a proof-of-concept: it only works with the exampled input data.



            It could be enhanced by:




            • reading the entire (unsplit) line to match it against a regex via the [[ command (in place of [) along with its =~ operator, like in: while read line && ! [[ "${line}" =~ four ]] but beware the then additional complexity given by bash’s own escaping rules if the regex gets more complex than a simple "four"; also note the ! preceding the [[ to negate the test

            • joining the [ (or [[) command with the two read and the && echo ... together inside the while loop, to not stop after first match, like in:


            { while read letters _ ; do [ "${letters}" = four ] && read && read _ number _ && echo ${number} ; done ; } < data.txt


            Note also the change of the comparison operator. However beware of missing possibly adjacent matching lines. In order to address this possibility you’d need some kind of look-ahead or back-caching, for which you’d need some more advanced bash constructs.



            Lastly, of course you can rather output the entire unsplit line via read line && echo ${line} in place of read _ number _ && echo ${number}






            share|improve this answer










            New contributor




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










            You already got very good answers, which are easily the true go-to solutions for one-liners, but just in case you'd like or need to do it pure-bash only you might start from the following:



            { while read letters _ && [ "${letters}" != four ] ; do :; done ; read && read _ number _ && echo ${number} ; } < data.txt


            It only yields the first occurrence of "four".



            Here I used _ as the name for a placeholder variable, i.e. a variable that receives values to be discarded, and as an "added bonus" you have the | cut -f2 result already built into the script.



            Also please note that above script is just a proof-of-concept: it only works with the exampled input data.



            It could be enhanced by:




            • reading the entire (unsplit) line to match it against a regex via the [[ command (in place of [) along with its =~ operator, like in: while read line && ! [[ "${line}" =~ four ]] but beware the then additional complexity given by bash’s own escaping rules if the regex gets more complex than a simple "four"; also note the ! preceding the [[ to negate the test

            • joining the [ (or [[) command with the two read and the && echo ... together inside the while loop, to not stop after first match, like in:


            { while read letters _ ; do [ "${letters}" = four ] && read && read _ number _ && echo ${number} ; done ; } < data.txt


            Note also the change of the comparison operator. However beware of missing possibly adjacent matching lines. In order to address this possibility you’d need some kind of look-ahead or back-caching, for which you’d need some more advanced bash constructs.



            Lastly, of course you can rather output the entire unsplit line via read line && echo ${line} in place of read _ number _ && echo ${number}







            share|improve this answer










            New contributor




            LL3 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 3 hours ago





















            New contributor




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









            answered 14 hours ago









            LL3LL3

            12




            12




            New contributor




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





            New contributor





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






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













            • So you’re assuming that the actual data is exactly like the sample data — the pattern to be searched for is a simple word that appears as a whole word, by itself, as the first word on a line.  But the question doesn’t say that; the sample data should be considered as just an example.  What if the line matching four actually says “I have fourteen cats.”?  What if the user actually wants to do this with a non-trivial regular expression (e.g., fox*ur)? … (Cont’d)

              – Scott
              5 hours ago











            • (Cont’d) …  What’s worse, the question clearly says that it wants to get the n-th (second) line after the line that matched — not the second word from that line.  Inasmuch as | cut -d' ' -f2 was also given as an example, baking it into your answer doesn’t earn you any points. … … … … … … … … … … … … … … Aside from that, this is a valid contribution to the discussion.  When you fix the above problems, consider showing two versions: one that finds the first match and stops, and another that finds all the matches.

              – Scott
              5 hours ago













            • @Scott: Well, my "script" is an example too, as much as the question’s information is an example itself - after all I did say "you could start with the following", and I suppose the script does look like just the proof-of-concept it indeed is. But I should make that clearer, agreed. Then, should I provide that much more functionality than explicitly requested ? In order to implement those additional features the script might easily become way more complex than it already is. Wouldn’t that risk to be an overkill ? I think I’d rather wait for explicit inquiries, if and when any (cont'd)

              – LL3
              5 hours ago











            • (cont'd) Wrt the “doing away the cut -f2 part”, it was certainly not for gaining points (nor is my entire contribution as a whole, considering that it is in general quite inferior (ie more complicated) to the other solutions), rather it just cost nothing to do it rather than not, considering that the question mentioned it as a likely subsequent processing of the input data. I contribute with a HTH mindset, I can do without an upvote and am happy with just a “nice, thank you”.

              – LL3
              5 hours ago



















            • So you’re assuming that the actual data is exactly like the sample data — the pattern to be searched for is a simple word that appears as a whole word, by itself, as the first word on a line.  But the question doesn’t say that; the sample data should be considered as just an example.  What if the line matching four actually says “I have fourteen cats.”?  What if the user actually wants to do this with a non-trivial regular expression (e.g., fox*ur)? … (Cont’d)

              – Scott
              5 hours ago











            • (Cont’d) …  What’s worse, the question clearly says that it wants to get the n-th (second) line after the line that matched — not the second word from that line.  Inasmuch as | cut -d' ' -f2 was also given as an example, baking it into your answer doesn’t earn you any points. … … … … … … … … … … … … … … Aside from that, this is a valid contribution to the discussion.  When you fix the above problems, consider showing two versions: one that finds the first match and stops, and another that finds all the matches.

              – Scott
              5 hours ago













            • @Scott: Well, my "script" is an example too, as much as the question’s information is an example itself - after all I did say "you could start with the following", and I suppose the script does look like just the proof-of-concept it indeed is. But I should make that clearer, agreed. Then, should I provide that much more functionality than explicitly requested ? In order to implement those additional features the script might easily become way more complex than it already is. Wouldn’t that risk to be an overkill ? I think I’d rather wait for explicit inquiries, if and when any (cont'd)

              – LL3
              5 hours ago











            • (cont'd) Wrt the “doing away the cut -f2 part”, it was certainly not for gaining points (nor is my entire contribution as a whole, considering that it is in general quite inferior (ie more complicated) to the other solutions), rather it just cost nothing to do it rather than not, considering that the question mentioned it as a likely subsequent processing of the input data. I contribute with a HTH mindset, I can do without an upvote and am happy with just a “nice, thank you”.

              – LL3
              5 hours ago

















            So you’re assuming that the actual data is exactly like the sample data — the pattern to be searched for is a simple word that appears as a whole word, by itself, as the first word on a line.  But the question doesn’t say that; the sample data should be considered as just an example.  What if the line matching four actually says “I have fourteen cats.”?  What if the user actually wants to do this with a non-trivial regular expression (e.g., fox*ur)? … (Cont’d)

            – Scott
            5 hours ago





            So you’re assuming that the actual data is exactly like the sample data — the pattern to be searched for is a simple word that appears as a whole word, by itself, as the first word on a line.  But the question doesn’t say that; the sample data should be considered as just an example.  What if the line matching four actually says “I have fourteen cats.”?  What if the user actually wants to do this with a non-trivial regular expression (e.g., fox*ur)? … (Cont’d)

            – Scott
            5 hours ago













            (Cont’d) …  What’s worse, the question clearly says that it wants to get the n-th (second) line after the line that matched — not the second word from that line.  Inasmuch as | cut -d' ' -f2 was also given as an example, baking it into your answer doesn’t earn you any points. … … … … … … … … … … … … … … Aside from that, this is a valid contribution to the discussion.  When you fix the above problems, consider showing two versions: one that finds the first match and stops, and another that finds all the matches.

            – Scott
            5 hours ago







            (Cont’d) …  What’s worse, the question clearly says that it wants to get the n-th (second) line after the line that matched — not the second word from that line.  Inasmuch as | cut -d' ' -f2 was also given as an example, baking it into your answer doesn’t earn you any points. … … … … … … … … … … … … … … Aside from that, this is a valid contribution to the discussion.  When you fix the above problems, consider showing two versions: one that finds the first match and stops, and another that finds all the matches.

            – Scott
            5 hours ago















            @Scott: Well, my "script" is an example too, as much as the question’s information is an example itself - after all I did say "you could start with the following", and I suppose the script does look like just the proof-of-concept it indeed is. But I should make that clearer, agreed. Then, should I provide that much more functionality than explicitly requested ? In order to implement those additional features the script might easily become way more complex than it already is. Wouldn’t that risk to be an overkill ? I think I’d rather wait for explicit inquiries, if and when any (cont'd)

            – LL3
            5 hours ago





            @Scott: Well, my "script" is an example too, as much as the question’s information is an example itself - after all I did say "you could start with the following", and I suppose the script does look like just the proof-of-concept it indeed is. But I should make that clearer, agreed. Then, should I provide that much more functionality than explicitly requested ? In order to implement those additional features the script might easily become way more complex than it already is. Wouldn’t that risk to be an overkill ? I think I’d rather wait for explicit inquiries, if and when any (cont'd)

            – LL3
            5 hours ago













            (cont'd) Wrt the “doing away the cut -f2 part”, it was certainly not for gaining points (nor is my entire contribution as a whole, considering that it is in general quite inferior (ie more complicated) to the other solutions), rather it just cost nothing to do it rather than not, considering that the question mentioned it as a likely subsequent processing of the input data. I contribute with a HTH mindset, I can do without an upvote and am happy with just a “nice, thank you”.

            – LL3
            5 hours ago





            (cont'd) Wrt the “doing away the cut -f2 part”, it was certainly not for gaining points (nor is my entire contribution as a whole, considering that it is in general quite inferior (ie more complicated) to the other solutions), rather it just cost nothing to do it rather than not, considering that the question mentioned it as a likely subsequent processing of the input data. I contribute with a HTH mindset, I can do without an upvote and am happy with just a “nice, thank you”.

            – LL3
            5 hours ago


















            draft saved

            draft discarded




















































            Thanks for contributing an answer to Super User!


            • 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%2fsuperuser.com%2fquestions%2f1414661%2fhow-to-get-the-n-th-line-after-a-grepped-one%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

            "Incorrect syntax near the keyword 'ON'. (on update cascade, on delete cascade,)

            Alcedinidae

            RAC Tourist Trophy