grep to return Nth and Mth lines before and after the match

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








up vote
11
down vote

favorite
2












I know that with grep I can use the fields -A and -B to pull previous and next lines from a match.



However they pull in all lines between the match based on however many lines are specified.



grep -r -i -B 5 -A 5 "match" 


I'd like to only receive the 5th line before a match and the 5th line after the match in addition to the matched line and not get the lines between.



Is there a way to do this with the grep?







share|improve this question


















  • 1




    You could do it by piping it into sed. I just tested this and it worked, but it only worked when there was 1 exact match in the file: grep -r -i -B 5 -A 5 "match" | sed -e 1b -e '$!d'
    – Terrance
    May 10 at 16:33










  • @Terrance thanks for the suggestion, as you mention, since I am collecting 1000's of lines this won't work.
    – chollida
    May 10 at 16:36










  • I don't think grep will work by itself... I'm working on a bash script for you
    – Joshua Besneatte
    May 10 at 16:41










  • No problem! Kind of interested in seeing what answers you get. =)
    – Terrance
    May 10 at 16:48










  • is this in one file or in multiple files?
    – Joshua Besneatte
    May 10 at 17:34














up vote
11
down vote

favorite
2












I know that with grep I can use the fields -A and -B to pull previous and next lines from a match.



However they pull in all lines between the match based on however many lines are specified.



grep -r -i -B 5 -A 5 "match" 


I'd like to only receive the 5th line before a match and the 5th line after the match in addition to the matched line and not get the lines between.



Is there a way to do this with the grep?







share|improve this question


















  • 1




    You could do it by piping it into sed. I just tested this and it worked, but it only worked when there was 1 exact match in the file: grep -r -i -B 5 -A 5 "match" | sed -e 1b -e '$!d'
    – Terrance
    May 10 at 16:33










  • @Terrance thanks for the suggestion, as you mention, since I am collecting 1000's of lines this won't work.
    – chollida
    May 10 at 16:36










  • I don't think grep will work by itself... I'm working on a bash script for you
    – Joshua Besneatte
    May 10 at 16:41










  • No problem! Kind of interested in seeing what answers you get. =)
    – Terrance
    May 10 at 16:48










  • is this in one file or in multiple files?
    – Joshua Besneatte
    May 10 at 17:34












up vote
11
down vote

favorite
2









up vote
11
down vote

favorite
2






2





I know that with grep I can use the fields -A and -B to pull previous and next lines from a match.



However they pull in all lines between the match based on however many lines are specified.



grep -r -i -B 5 -A 5 "match" 


I'd like to only receive the 5th line before a match and the 5th line after the match in addition to the matched line and not get the lines between.



Is there a way to do this with the grep?







share|improve this question














I know that with grep I can use the fields -A and -B to pull previous and next lines from a match.



However they pull in all lines between the match based on however many lines are specified.



grep -r -i -B 5 -A 5 "match" 


I'd like to only receive the 5th line before a match and the 5th line after the match in addition to the matched line and not get the lines between.



Is there a way to do this with the grep?









share|improve this question













share|improve this question




share|improve this question








edited May 10 at 19:25









αғsнιη

23.1k2191150




23.1k2191150










asked May 10 at 16:20









chollida

1609




1609







  • 1




    You could do it by piping it into sed. I just tested this and it worked, but it only worked when there was 1 exact match in the file: grep -r -i -B 5 -A 5 "match" | sed -e 1b -e '$!d'
    – Terrance
    May 10 at 16:33










  • @Terrance thanks for the suggestion, as you mention, since I am collecting 1000's of lines this won't work.
    – chollida
    May 10 at 16:36










  • I don't think grep will work by itself... I'm working on a bash script for you
    – Joshua Besneatte
    May 10 at 16:41










  • No problem! Kind of interested in seeing what answers you get. =)
    – Terrance
    May 10 at 16:48










  • is this in one file or in multiple files?
    – Joshua Besneatte
    May 10 at 17:34












  • 1




    You could do it by piping it into sed. I just tested this and it worked, but it only worked when there was 1 exact match in the file: grep -r -i -B 5 -A 5 "match" | sed -e 1b -e '$!d'
    – Terrance
    May 10 at 16:33










  • @Terrance thanks for the suggestion, as you mention, since I am collecting 1000's of lines this won't work.
    – chollida
    May 10 at 16:36










  • I don't think grep will work by itself... I'm working on a bash script for you
    – Joshua Besneatte
    May 10 at 16:41










  • No problem! Kind of interested in seeing what answers you get. =)
    – Terrance
    May 10 at 16:48










  • is this in one file or in multiple files?
    – Joshua Besneatte
    May 10 at 17:34







1




1




You could do it by piping it into sed. I just tested this and it worked, but it only worked when there was 1 exact match in the file: grep -r -i -B 5 -A 5 "match" | sed -e 1b -e '$!d'
– Terrance
May 10 at 16:33




You could do it by piping it into sed. I just tested this and it worked, but it only worked when there was 1 exact match in the file: grep -r -i -B 5 -A 5 "match" | sed -e 1b -e '$!d'
– Terrance
May 10 at 16:33












@Terrance thanks for the suggestion, as you mention, since I am collecting 1000's of lines this won't work.
– chollida
May 10 at 16:36




@Terrance thanks for the suggestion, as you mention, since I am collecting 1000's of lines this won't work.
– chollida
May 10 at 16:36












I don't think grep will work by itself... I'm working on a bash script for you
– Joshua Besneatte
May 10 at 16:41




I don't think grep will work by itself... I'm working on a bash script for you
– Joshua Besneatte
May 10 at 16:41












No problem! Kind of interested in seeing what answers you get. =)
– Terrance
May 10 at 16:48




No problem! Kind of interested in seeing what answers you get. =)
– Terrance
May 10 at 16:48












is this in one file or in multiple files?
– Joshua Besneatte
May 10 at 17:34




is this in one file or in multiple files?
– Joshua Besneatte
May 10 at 17:34










5 Answers
5






active

oldest

votes

















up vote
13
down vote



accepted










If:



cat file




a
b
c
d
e
f match
g
h
i match
j
k
l
m
n
o


Then:



awk '
line[NR] = $0
/match/ matched[NR]
END
for (nr in matched)
for (n=nr-5; n<=nr+5; n+=5)
print line[n]

' file




a
f match
k
d
i match
n





share|improve this answer






















  • +1, but could you explain the semantics of /match/ matched[NR]? I've never seen an array or variable as an entire command. Is it putting the current record number of each matched line into the array.
    – Joe
    May 17 at 3:51










  • This is an awk oddity:if you reference an array element without assignment, that key is added to the array (without a value). Then that key shows up in the expression key in array. What I'm doing is remembering the line numbers where the pattern appears
    – glenn jackman
    May 17 at 11:45


















up vote
7
down vote













It can't be done with only grep. If ed's an option:



ed -s file << 'EOF' 
g/match/-5p
+5p
+5p
EOF


The script basically says: for every match of /match/, print the line 5 lines before that, then 5 lines after that, then 5 lines after that.






share|improve this answer


















  • 5




    @ubashu Do you think it'll be more helpful to the OP giving a simple flat "it can't be done with grep"? I'm providing what I believe to be a good alternative to solve OP's problem. From the Help Center: "What, specifically, is the question asking for? Make sure your answer provides that – or a viable alternative. The answer can be 'don’t do that', but it should also include 'try this instead'."
    – JoL
    May 11 at 0:16











  • ed is always an answer, because ed is the standard text editor.
    – dessert
    May 11 at 8:28







  • 5




    @ubashu Though it's not a grep answer, the answer of "You can't do it with X, but you can do it with Y, here's how" is still a valid answer since you not only answer OP's question but you also provide an alternative that would work. This is a valid type of answer here.
    – Thomas Ward♦
    May 11 at 13:23


















up vote
6
down vote













This is basically Glenn's solution, but implemented with Bash, Grep, and sed.



grep -n match file |
while IFS=: read nr _; do
sed -ns "$((nr-5))p; $((nr))p; $((nr+5))p" file
done


Note that line numbers less than 1 will make sed error, and line numbers greater than the number of lines in the file will make it print nothing.



This is just the bare minimum. To make it work recursively and handle the above line number cases would take some doing.






share|improve this answer





























    up vote
    6
    down vote













    awk '/match/system("sed -n "" NR-5 "p;" NR "p;" NR+5 "p" " FILENAME)' infile


    Here we are using awk's system(command) function to call external sed command to print the lines which awk matched with pattern match with 5th lines before and after the match.



    The syntax is easy, you just need to put the external command itself inside double-quote as well as its switches and escape the things you want exactly pass to the command, everything else related to the awk itself options should be outside of the quotes. So the below sed:



    "sed -n "" NR-5 "p;" NR "p;" NR+5 "p" " FILENAME


    translate into:



    sed -n "NR-5p; NRp; NR+5p" FILENAME


    NR is the line number that matched with the pattern match and FILENAME is the of current processing filename passing by awk.






    share|improve this answer





























      up vote
      2
      down vote













      using @glenn's example text file and using perl instead of awk:



      $ perl -n0E 'say /(.*n)(?=(?:.*n)4(.*match.*n)(?:.*n)4(.*n))/g' ex


      will give the same results, but running faster:



      a
      f match
      k
      d
      i match
      n





      share|improve this answer






















      • João, you're showing up in the LQ review queue and @waltinator voted to delete, so next time be a tiny bit more verbose... ;-) Also +1 to get you out of the LQ queue... :P
        – Fabby
        May 11 at 13:48







      • 1




        @JJoao Low quality review queue. Your answer probably got picked up there because it was 90% code.
        – wjandrea
        May 11 at 16:29







      • 1




        @JJoao The 90% figure is just my way of explaining it. I don't know what heuristics are actually used.
        – wjandrea
        May 11 at 18:41






      • 1




        Menos café, mais escrita! @JJoao :D ;-) :D
        – Fabby
        May 11 at 18:51






      • 1




        @Fabby: Sem café nada funciona :D -- probably it would show up in the LCQ (=low coffee queue)
        – JJoao
        May 11 at 21:00










      Your Answer







      StackExchange.ready(function()
      var channelOptions =
      tags: "".split(" "),
      id: "89"
      ;
      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: true,
      noModals: false,
      showLowRepImageUploadWarning: true,
      reputationToPostImages: 10,
      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%2faskubuntu.com%2fquestions%2f1034562%2fgrep-to-return-nth-and-mth-lines-before-and-after-the-match%23new-answer', 'question_page');

      );

      Post as a guest






























      5 Answers
      5






      active

      oldest

      votes








      5 Answers
      5






      active

      oldest

      votes









      active

      oldest

      votes






      active

      oldest

      votes








      up vote
      13
      down vote



      accepted










      If:



      cat file




      a
      b
      c
      d
      e
      f match
      g
      h
      i match
      j
      k
      l
      m
      n
      o


      Then:



      awk '
      line[NR] = $0
      /match/ matched[NR]
      END
      for (nr in matched)
      for (n=nr-5; n<=nr+5; n+=5)
      print line[n]

      ' file




      a
      f match
      k
      d
      i match
      n





      share|improve this answer






















      • +1, but could you explain the semantics of /match/ matched[NR]? I've never seen an array or variable as an entire command. Is it putting the current record number of each matched line into the array.
        – Joe
        May 17 at 3:51










      • This is an awk oddity:if you reference an array element without assignment, that key is added to the array (without a value). Then that key shows up in the expression key in array. What I'm doing is remembering the line numbers where the pattern appears
        – glenn jackman
        May 17 at 11:45















      up vote
      13
      down vote



      accepted










      If:



      cat file




      a
      b
      c
      d
      e
      f match
      g
      h
      i match
      j
      k
      l
      m
      n
      o


      Then:



      awk '
      line[NR] = $0
      /match/ matched[NR]
      END
      for (nr in matched)
      for (n=nr-5; n<=nr+5; n+=5)
      print line[n]

      ' file




      a
      f match
      k
      d
      i match
      n





      share|improve this answer






















      • +1, but could you explain the semantics of /match/ matched[NR]? I've never seen an array or variable as an entire command. Is it putting the current record number of each matched line into the array.
        – Joe
        May 17 at 3:51










      • This is an awk oddity:if you reference an array element without assignment, that key is added to the array (without a value). Then that key shows up in the expression key in array. What I'm doing is remembering the line numbers where the pattern appears
        – glenn jackman
        May 17 at 11:45













      up vote
      13
      down vote



      accepted







      up vote
      13
      down vote



      accepted






      If:



      cat file




      a
      b
      c
      d
      e
      f match
      g
      h
      i match
      j
      k
      l
      m
      n
      o


      Then:



      awk '
      line[NR] = $0
      /match/ matched[NR]
      END
      for (nr in matched)
      for (n=nr-5; n<=nr+5; n+=5)
      print line[n]

      ' file




      a
      f match
      k
      d
      i match
      n





      share|improve this answer














      If:



      cat file




      a
      b
      c
      d
      e
      f match
      g
      h
      i match
      j
      k
      l
      m
      n
      o


      Then:



      awk '
      line[NR] = $0
      /match/ matched[NR]
      END
      for (nr in matched)
      for (n=nr-5; n<=nr+5; n+=5)
      print line[n]

      ' file




      a
      f match
      k
      d
      i match
      n






      share|improve this answer














      share|improve this answer



      share|improve this answer








      edited May 10 at 17:00

























      answered May 10 at 16:36









      glenn jackman

      11.8k2241




      11.8k2241











      • +1, but could you explain the semantics of /match/ matched[NR]? I've never seen an array or variable as an entire command. Is it putting the current record number of each matched line into the array.
        – Joe
        May 17 at 3:51










      • This is an awk oddity:if you reference an array element without assignment, that key is added to the array (without a value). Then that key shows up in the expression key in array. What I'm doing is remembering the line numbers where the pattern appears
        – glenn jackman
        May 17 at 11:45

















      • +1, but could you explain the semantics of /match/ matched[NR]? I've never seen an array or variable as an entire command. Is it putting the current record number of each matched line into the array.
        – Joe
        May 17 at 3:51










      • This is an awk oddity:if you reference an array element without assignment, that key is added to the array (without a value). Then that key shows up in the expression key in array. What I'm doing is remembering the line numbers where the pattern appears
        – glenn jackman
        May 17 at 11:45
















      +1, but could you explain the semantics of /match/ matched[NR]? I've never seen an array or variable as an entire command. Is it putting the current record number of each matched line into the array.
      – Joe
      May 17 at 3:51




      +1, but could you explain the semantics of /match/ matched[NR]? I've never seen an array or variable as an entire command. Is it putting the current record number of each matched line into the array.
      – Joe
      May 17 at 3:51












      This is an awk oddity:if you reference an array element without assignment, that key is added to the array (without a value). Then that key shows up in the expression key in array. What I'm doing is remembering the line numbers where the pattern appears
      – glenn jackman
      May 17 at 11:45





      This is an awk oddity:if you reference an array element without assignment, that key is added to the array (without a value). Then that key shows up in the expression key in array. What I'm doing is remembering the line numbers where the pattern appears
      – glenn jackman
      May 17 at 11:45













      up vote
      7
      down vote













      It can't be done with only grep. If ed's an option:



      ed -s file << 'EOF' 
      g/match/-5p
      +5p
      +5p
      EOF


      The script basically says: for every match of /match/, print the line 5 lines before that, then 5 lines after that, then 5 lines after that.






      share|improve this answer


















      • 5




        @ubashu Do you think it'll be more helpful to the OP giving a simple flat "it can't be done with grep"? I'm providing what I believe to be a good alternative to solve OP's problem. From the Help Center: "What, specifically, is the question asking for? Make sure your answer provides that – or a viable alternative. The answer can be 'don’t do that', but it should also include 'try this instead'."
        – JoL
        May 11 at 0:16











      • ed is always an answer, because ed is the standard text editor.
        – dessert
        May 11 at 8:28







      • 5




        @ubashu Though it's not a grep answer, the answer of "You can't do it with X, but you can do it with Y, here's how" is still a valid answer since you not only answer OP's question but you also provide an alternative that would work. This is a valid type of answer here.
        – Thomas Ward♦
        May 11 at 13:23















      up vote
      7
      down vote













      It can't be done with only grep. If ed's an option:



      ed -s file << 'EOF' 
      g/match/-5p
      +5p
      +5p
      EOF


      The script basically says: for every match of /match/, print the line 5 lines before that, then 5 lines after that, then 5 lines after that.






      share|improve this answer


















      • 5




        @ubashu Do you think it'll be more helpful to the OP giving a simple flat "it can't be done with grep"? I'm providing what I believe to be a good alternative to solve OP's problem. From the Help Center: "What, specifically, is the question asking for? Make sure your answer provides that – or a viable alternative. The answer can be 'don’t do that', but it should also include 'try this instead'."
        – JoL
        May 11 at 0:16











      • ed is always an answer, because ed is the standard text editor.
        – dessert
        May 11 at 8:28







      • 5




        @ubashu Though it's not a grep answer, the answer of "You can't do it with X, but you can do it with Y, here's how" is still a valid answer since you not only answer OP's question but you also provide an alternative that would work. This is a valid type of answer here.
        – Thomas Ward♦
        May 11 at 13:23













      up vote
      7
      down vote










      up vote
      7
      down vote









      It can't be done with only grep. If ed's an option:



      ed -s file << 'EOF' 
      g/match/-5p
      +5p
      +5p
      EOF


      The script basically says: for every match of /match/, print the line 5 lines before that, then 5 lines after that, then 5 lines after that.






      share|improve this answer














      It can't be done with only grep. If ed's an option:



      ed -s file << 'EOF' 
      g/match/-5p
      +5p
      +5p
      EOF


      The script basically says: for every match of /match/, print the line 5 lines before that, then 5 lines after that, then 5 lines after that.







      share|improve this answer














      share|improve this answer



      share|improve this answer








      edited May 11 at 0:27

























      answered May 10 at 23:25









      JoL

      1,04427




      1,04427







      • 5




        @ubashu Do you think it'll be more helpful to the OP giving a simple flat "it can't be done with grep"? I'm providing what I believe to be a good alternative to solve OP's problem. From the Help Center: "What, specifically, is the question asking for? Make sure your answer provides that – or a viable alternative. The answer can be 'don’t do that', but it should also include 'try this instead'."
        – JoL
        May 11 at 0:16











      • ed is always an answer, because ed is the standard text editor.
        – dessert
        May 11 at 8:28







      • 5




        @ubashu Though it's not a grep answer, the answer of "You can't do it with X, but you can do it with Y, here's how" is still a valid answer since you not only answer OP's question but you also provide an alternative that would work. This is a valid type of answer here.
        – Thomas Ward♦
        May 11 at 13:23













      • 5




        @ubashu Do you think it'll be more helpful to the OP giving a simple flat "it can't be done with grep"? I'm providing what I believe to be a good alternative to solve OP's problem. From the Help Center: "What, specifically, is the question asking for? Make sure your answer provides that – or a viable alternative. The answer can be 'don’t do that', but it should also include 'try this instead'."
        – JoL
        May 11 at 0:16











      • ed is always an answer, because ed is the standard text editor.
        – dessert
        May 11 at 8:28







      • 5




        @ubashu Though it's not a grep answer, the answer of "You can't do it with X, but you can do it with Y, here's how" is still a valid answer since you not only answer OP's question but you also provide an alternative that would work. This is a valid type of answer here.
        – Thomas Ward♦
        May 11 at 13:23








      5




      5




      @ubashu Do you think it'll be more helpful to the OP giving a simple flat "it can't be done with grep"? I'm providing what I believe to be a good alternative to solve OP's problem. From the Help Center: "What, specifically, is the question asking for? Make sure your answer provides that – or a viable alternative. The answer can be 'don’t do that', but it should also include 'try this instead'."
      – JoL
      May 11 at 0:16





      @ubashu Do you think it'll be more helpful to the OP giving a simple flat "it can't be done with grep"? I'm providing what I believe to be a good alternative to solve OP's problem. From the Help Center: "What, specifically, is the question asking for? Make sure your answer provides that – or a viable alternative. The answer can be 'don’t do that', but it should also include 'try this instead'."
      – JoL
      May 11 at 0:16













      ed is always an answer, because ed is the standard text editor.
      – dessert
      May 11 at 8:28





      ed is always an answer, because ed is the standard text editor.
      – dessert
      May 11 at 8:28





      5




      5




      @ubashu Though it's not a grep answer, the answer of "You can't do it with X, but you can do it with Y, here's how" is still a valid answer since you not only answer OP's question but you also provide an alternative that would work. This is a valid type of answer here.
      – Thomas Ward♦
      May 11 at 13:23





      @ubashu Though it's not a grep answer, the answer of "You can't do it with X, but you can do it with Y, here's how" is still a valid answer since you not only answer OP's question but you also provide an alternative that would work. This is a valid type of answer here.
      – Thomas Ward♦
      May 11 at 13:23











      up vote
      6
      down vote













      This is basically Glenn's solution, but implemented with Bash, Grep, and sed.



      grep -n match file |
      while IFS=: read nr _; do
      sed -ns "$((nr-5))p; $((nr))p; $((nr+5))p" file
      done


      Note that line numbers less than 1 will make sed error, and line numbers greater than the number of lines in the file will make it print nothing.



      This is just the bare minimum. To make it work recursively and handle the above line number cases would take some doing.






      share|improve this answer


























        up vote
        6
        down vote













        This is basically Glenn's solution, but implemented with Bash, Grep, and sed.



        grep -n match file |
        while IFS=: read nr _; do
        sed -ns "$((nr-5))p; $((nr))p; $((nr+5))p" file
        done


        Note that line numbers less than 1 will make sed error, and line numbers greater than the number of lines in the file will make it print nothing.



        This is just the bare minimum. To make it work recursively and handle the above line number cases would take some doing.






        share|improve this answer
























          up vote
          6
          down vote










          up vote
          6
          down vote









          This is basically Glenn's solution, but implemented with Bash, Grep, and sed.



          grep -n match file |
          while IFS=: read nr _; do
          sed -ns "$((nr-5))p; $((nr))p; $((nr+5))p" file
          done


          Note that line numbers less than 1 will make sed error, and line numbers greater than the number of lines in the file will make it print nothing.



          This is just the bare minimum. To make it work recursively and handle the above line number cases would take some doing.






          share|improve this answer














          This is basically Glenn's solution, but implemented with Bash, Grep, and sed.



          grep -n match file |
          while IFS=: read nr _; do
          sed -ns "$((nr-5))p; $((nr))p; $((nr+5))p" file
          done


          Note that line numbers less than 1 will make sed error, and line numbers greater than the number of lines in the file will make it print nothing.



          This is just the bare minimum. To make it work recursively and handle the above line number cases would take some doing.







          share|improve this answer














          share|improve this answer



          share|improve this answer








          edited May 10 at 19:34

























          answered May 10 at 19:13









          wjandrea

          7,14242155




          7,14242155




















              up vote
              6
              down vote













              awk '/match/system("sed -n "" NR-5 "p;" NR "p;" NR+5 "p" " FILENAME)' infile


              Here we are using awk's system(command) function to call external sed command to print the lines which awk matched with pattern match with 5th lines before and after the match.



              The syntax is easy, you just need to put the external command itself inside double-quote as well as its switches and escape the things you want exactly pass to the command, everything else related to the awk itself options should be outside of the quotes. So the below sed:



              "sed -n "" NR-5 "p;" NR "p;" NR+5 "p" " FILENAME


              translate into:



              sed -n "NR-5p; NRp; NR+5p" FILENAME


              NR is the line number that matched with the pattern match and FILENAME is the of current processing filename passing by awk.






              share|improve this answer


























                up vote
                6
                down vote













                awk '/match/system("sed -n "" NR-5 "p;" NR "p;" NR+5 "p" " FILENAME)' infile


                Here we are using awk's system(command) function to call external sed command to print the lines which awk matched with pattern match with 5th lines before and after the match.



                The syntax is easy, you just need to put the external command itself inside double-quote as well as its switches and escape the things you want exactly pass to the command, everything else related to the awk itself options should be outside of the quotes. So the below sed:



                "sed -n "" NR-5 "p;" NR "p;" NR+5 "p" " FILENAME


                translate into:



                sed -n "NR-5p; NRp; NR+5p" FILENAME


                NR is the line number that matched with the pattern match and FILENAME is the of current processing filename passing by awk.






                share|improve this answer
























                  up vote
                  6
                  down vote










                  up vote
                  6
                  down vote









                  awk '/match/system("sed -n "" NR-5 "p;" NR "p;" NR+5 "p" " FILENAME)' infile


                  Here we are using awk's system(command) function to call external sed command to print the lines which awk matched with pattern match with 5th lines before and after the match.



                  The syntax is easy, you just need to put the external command itself inside double-quote as well as its switches and escape the things you want exactly pass to the command, everything else related to the awk itself options should be outside of the quotes. So the below sed:



                  "sed -n "" NR-5 "p;" NR "p;" NR+5 "p" " FILENAME


                  translate into:



                  sed -n "NR-5p; NRp; NR+5p" FILENAME


                  NR is the line number that matched with the pattern match and FILENAME is the of current processing filename passing by awk.






                  share|improve this answer














                  awk '/match/system("sed -n "" NR-5 "p;" NR "p;" NR+5 "p" " FILENAME)' infile


                  Here we are using awk's system(command) function to call external sed command to print the lines which awk matched with pattern match with 5th lines before and after the match.



                  The syntax is easy, you just need to put the external command itself inside double-quote as well as its switches and escape the things you want exactly pass to the command, everything else related to the awk itself options should be outside of the quotes. So the below sed:



                  "sed -n "" NR-5 "p;" NR "p;" NR+5 "p" " FILENAME


                  translate into:



                  sed -n "NR-5p; NRp; NR+5p" FILENAME


                  NR is the line number that matched with the pattern match and FILENAME is the of current processing filename passing by awk.







                  share|improve this answer














                  share|improve this answer



                  share|improve this answer








                  edited May 10 at 20:07

























                  answered May 10 at 18:51









                  αғsнιη

                  23.1k2191150




                  23.1k2191150




















                      up vote
                      2
                      down vote













                      using @glenn's example text file and using perl instead of awk:



                      $ perl -n0E 'say /(.*n)(?=(?:.*n)4(.*match.*n)(?:.*n)4(.*n))/g' ex


                      will give the same results, but running faster:



                      a
                      f match
                      k
                      d
                      i match
                      n





                      share|improve this answer






















                      • João, you're showing up in the LQ review queue and @waltinator voted to delete, so next time be a tiny bit more verbose... ;-) Also +1 to get you out of the LQ queue... :P
                        – Fabby
                        May 11 at 13:48







                      • 1




                        @JJoao Low quality review queue. Your answer probably got picked up there because it was 90% code.
                        – wjandrea
                        May 11 at 16:29







                      • 1




                        @JJoao The 90% figure is just my way of explaining it. I don't know what heuristics are actually used.
                        – wjandrea
                        May 11 at 18:41






                      • 1




                        Menos café, mais escrita! @JJoao :D ;-) :D
                        – Fabby
                        May 11 at 18:51






                      • 1




                        @Fabby: Sem café nada funciona :D -- probably it would show up in the LCQ (=low coffee queue)
                        – JJoao
                        May 11 at 21:00














                      up vote
                      2
                      down vote













                      using @glenn's example text file and using perl instead of awk:



                      $ perl -n0E 'say /(.*n)(?=(?:.*n)4(.*match.*n)(?:.*n)4(.*n))/g' ex


                      will give the same results, but running faster:



                      a
                      f match
                      k
                      d
                      i match
                      n





                      share|improve this answer






















                      • João, you're showing up in the LQ review queue and @waltinator voted to delete, so next time be a tiny bit more verbose... ;-) Also +1 to get you out of the LQ queue... :P
                        – Fabby
                        May 11 at 13:48







                      • 1




                        @JJoao Low quality review queue. Your answer probably got picked up there because it was 90% code.
                        – wjandrea
                        May 11 at 16:29







                      • 1




                        @JJoao The 90% figure is just my way of explaining it. I don't know what heuristics are actually used.
                        – wjandrea
                        May 11 at 18:41






                      • 1




                        Menos café, mais escrita! @JJoao :D ;-) :D
                        – Fabby
                        May 11 at 18:51






                      • 1




                        @Fabby: Sem café nada funciona :D -- probably it would show up in the LCQ (=low coffee queue)
                        – JJoao
                        May 11 at 21:00












                      up vote
                      2
                      down vote










                      up vote
                      2
                      down vote









                      using @glenn's example text file and using perl instead of awk:



                      $ perl -n0E 'say /(.*n)(?=(?:.*n)4(.*match.*n)(?:.*n)4(.*n))/g' ex


                      will give the same results, but running faster:



                      a
                      f match
                      k
                      d
                      i match
                      n





                      share|improve this answer














                      using @glenn's example text file and using perl instead of awk:



                      $ perl -n0E 'say /(.*n)(?=(?:.*n)4(.*match.*n)(?:.*n)4(.*n))/g' ex


                      will give the same results, but running faster:



                      a
                      f match
                      k
                      d
                      i match
                      n






                      share|improve this answer














                      share|improve this answer



                      share|improve this answer








                      edited May 11 at 13:46









                      Fabby

                      24k1352150




                      24k1352150










                      answered May 11 at 10:18









                      JJoao

                      1,24059




                      1,24059











                      • João, you're showing up in the LQ review queue and @waltinator voted to delete, so next time be a tiny bit more verbose... ;-) Also +1 to get you out of the LQ queue... :P
                        – Fabby
                        May 11 at 13:48







                      • 1




                        @JJoao Low quality review queue. Your answer probably got picked up there because it was 90% code.
                        – wjandrea
                        May 11 at 16:29







                      • 1




                        @JJoao The 90% figure is just my way of explaining it. I don't know what heuristics are actually used.
                        – wjandrea
                        May 11 at 18:41






                      • 1




                        Menos café, mais escrita! @JJoao :D ;-) :D
                        – Fabby
                        May 11 at 18:51






                      • 1




                        @Fabby: Sem café nada funciona :D -- probably it would show up in the LCQ (=low coffee queue)
                        – JJoao
                        May 11 at 21:00
















                      • João, you're showing up in the LQ review queue and @waltinator voted to delete, so next time be a tiny bit more verbose... ;-) Also +1 to get you out of the LQ queue... :P
                        – Fabby
                        May 11 at 13:48







                      • 1




                        @JJoao Low quality review queue. Your answer probably got picked up there because it was 90% code.
                        – wjandrea
                        May 11 at 16:29







                      • 1




                        @JJoao The 90% figure is just my way of explaining it. I don't know what heuristics are actually used.
                        – wjandrea
                        May 11 at 18:41






                      • 1




                        Menos café, mais escrita! @JJoao :D ;-) :D
                        – Fabby
                        May 11 at 18:51






                      • 1




                        @Fabby: Sem café nada funciona :D -- probably it would show up in the LCQ (=low coffee queue)
                        – JJoao
                        May 11 at 21:00















                      João, you're showing up in the LQ review queue and @waltinator voted to delete, so next time be a tiny bit more verbose... ;-) Also +1 to get you out of the LQ queue... :P
                      – Fabby
                      May 11 at 13:48





                      João, you're showing up in the LQ review queue and @waltinator voted to delete, so next time be a tiny bit more verbose... ;-) Also +1 to get you out of the LQ queue... :P
                      – Fabby
                      May 11 at 13:48





                      1




                      1




                      @JJoao Low quality review queue. Your answer probably got picked up there because it was 90% code.
                      – wjandrea
                      May 11 at 16:29





                      @JJoao Low quality review queue. Your answer probably got picked up there because it was 90% code.
                      – wjandrea
                      May 11 at 16:29





                      1




                      1




                      @JJoao The 90% figure is just my way of explaining it. I don't know what heuristics are actually used.
                      – wjandrea
                      May 11 at 18:41




                      @JJoao The 90% figure is just my way of explaining it. I don't know what heuristics are actually used.
                      – wjandrea
                      May 11 at 18:41




                      1




                      1




                      Menos café, mais escrita! @JJoao :D ;-) :D
                      – Fabby
                      May 11 at 18:51




                      Menos café, mais escrita! @JJoao :D ;-) :D
                      – Fabby
                      May 11 at 18:51




                      1




                      1




                      @Fabby: Sem café nada funciona :D -- probably it would show up in the LCQ (=low coffee queue)
                      – JJoao
                      May 11 at 21:00




                      @Fabby: Sem café nada funciona :D -- probably it would show up in the LCQ (=low coffee queue)
                      – JJoao
                      May 11 at 21:00












                       

                      draft saved


                      draft discarded


























                       


                      draft saved


                      draft discarded














                      StackExchange.ready(
                      function ()
                      StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2faskubuntu.com%2fquestions%2f1034562%2fgrep-to-return-nth-and-mth-lines-before-and-after-the-match%23new-answer', 'question_page');

                      );

                      Post as a guest













































































                      Popular posts from this blog

                      pylint3 and pip3 broken

                      Missing snmpget and snmpwalk

                      How to enroll fingerprints to Ubuntu 17.10 with VFS491