How to display lines 2-4 after each grep result?

  • I'm parsing a mailbox file that stores e-mail server reports for unsuccessfully delivered e-mail. I wish to extract bad e-mail addresses, so that I remove them from the system. The log file looks like this:

    ...some content...
                       The mail system
    
    <[email protected]>: host mx1.hotmail.com[65.54.188.94] said: 550
        Requested action not taken: mailbox unavailable (in reply to RCPT TO
        command)
    
    ...some content...
                       The mail system
    
    <[email protected]>: host viking.optimumpro.net[79.101.51.82] said: 550
        Unknown user (in reply to RCPT TO command)
    
    ...some content...
                       The mail system
    
    <[email protected]>: host mta5.am0.yahoodns.net[74.6.140.64] said: 554
        delivery error: dd This user doesn't have a yahoo.com account
        ([email protected]) [0] - mta1172.mail.sk1.yahoo.com (in reply to end
        of DATA command)
    
    ...etc.
    

    E-mail address comes 2 lines after a line with "The mail system". Using grep like this gives me the "The mail system" line and the next two lines:

    grep -A 2 "The mail system" mbox_file
    

    However, I don't know how to remove the "The mail system" line and the second empty line from this output. I guess I could write PHP/Perl/Python script to do it, but I wonder if this is possible with grep or some other standard tool. I tried to give negative offset to -B parameter:

    grep -A 2 -B -2 "The mail system" mbox_file
    

    But grep complains:

    grep: -2: invalid context length argument
    

    Is there a way to do this with grep?

    -B accepts numeral as -A would, and it would display the previous lines before the match.

    Yes, that is true, but *Milan* isn't interested in what precedes the match... The problem he encountered is that -A and -B only accept positive values... and that in any case, -A and -B can't be used relative to each other, as he has attempted to do.

    Hum, just to make sure: those are dummy addresses that you did not (directly) extract from the file you were given, right ?

    @Matthieu M. no, they are from real log file. I figured since they are invalid addresses anyway, what's the point of inventing dummy addresses that might be valid.

  • Eugene S

    Eugene S Correct answer

    9 years ago

    The simplest way to solve it using grep only, is to pipe one more inverted grep at the end. For example:

    grep -A 4 "The mail system" temp.txt | grep -v "The mail system" | grep -v '^\d*$'
    

License under CC-BY-SA with attribution


Content dated before 6/26/2020 9:53 AM