How can I use the grep command to extract line which is the next line of greping line?

I have text file like (the specific part of the whole file);

!        lat             long          elev (m)
!      44.5199005      11.6468000       50.4276

I need to extract second line and save them in another text file. The numbers are variable and "!" syntax is also exist several times in the text. For the first line there is always 8 spaces between "!" and "lat" but this is not the case for the second line. Is there any command available to allow me to extract next line after grep "! lat" text


You can use grep -A1 'expression'

From the manual:

-A num
--after-context=num
    Print num lines of trailing context after matching lines.

In your case:

grep -A1 "!        lat" foo | grep -v "!        lat"

should work to extract the second line only.

Note:
You can use grep -P '^! {8}lat' instead of typing many . This is less error prone. The -P flag enables perl style regular expressions and {8} (There is a space before the '{') matches exactly 8 spaces.


You can get the desired output in one go of grep using -z option to treat the lines of input file to be separated by NUL characters rather than newline charaters so that newline characters can be matched literally. You can do:

grep -Pzo '!\s{8}lat[^\n]*\n\K[^\n]+' file.txt
  • -P will enable us to use PCRE, -o will get us the desired portion only

  • !\s{8}lat[^\n]*\n will match the line with lat after ! and 8 spaces, also it will match the trailing newline character, the \K will discard this match

  • [^\n]+ will then match the next line i.e. what we want as output.

Here i also assume that there is no space after lat, if there must be at least a space you can do:

grep -Pzo '!\s{8}lat\s+[^\n]*\n\K[^\n]+' file.txt

Example:

$ cat file.txt 
!        lat             long          elev (m)
!      44.5199005      11.6468000       50.4276
!      30.5199005      2445.6468000       23.89

$ grep -Pzo '!\s{8}lat[^\n]*\n\K[^\n]+' file.txt 
!      44.5199005      11.6468000       50.4276

  1. awk

    awk '/! {8}lat/ {a=1; next} a {a=0; print};' foo
    
  2. sed

    sed -n '/! \{8\}lat/{n;p}' foo