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

  • 1
    Do you need to use grep?
    – muru
    Oct 23 '15 at 12:03

You can use grep -A1 'expression'

From the manual:

-A 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.

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.

  • How can I save only the second line to another text file? Oct 23 '15 at 7:56
  • @deepblue_86: I edited my answer
    – Wayne_Yux
    Oct 23 '15 at 8:00
  • Can be simplified: grep -A1 "! lat" text | grep -v "! lat". No need for cat. (Comments remove multiple spaces, unfortunately!)
    – Byte Commander
    Oct 23 '15 at 8:01
  • true, but I think it is easier to read and understand as your "working through" the commands from left to right
    – Wayne_Yux
    Oct 23 '15 at 8:08
  • 1
    Note -E (extended regexp) suffices for the {8}, there is no need to use -P (perl regexp).
    – fedorqui
    Oct 23 '15 at 11:44

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


$ 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
  • 2
    It is more idiomatic to say something like awk 'f{print; exit} /^! {8}lat/ {f=1}' file. Note getline is not recommended in general.
    – fedorqui
    Oct 23 '15 at 9:25

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.