1

I have a file with the output as below

--B32934--
descr:     X
descr:     Y
descr:     Z
--B20484
descr:     A
descr:     B
descr:     C
--B41946
descr:     1
descr:     2
descr:     3
descr:     4

I just need the --BXXXX number and the first line, the rest of the lines need to be stripped out from the file. Is it possible to delete the lines >1 based on the pattern match --B?

For example under "--B32934" i just want "descr:X". The rest of the lines need to be deleted.

Desired result should look like this

--B32934--
descr:     X
fedorqui
  • 275,237
  • 103
  • 548
  • 598
venkyjack
  • 33
  • 7
  • 1
    post the desired result – RomanPerekhrest Jun 14 '17 at 11:01
  • Hello thanks for the reply. The desired result should look like this --B32934-- descr: X --B20484 descr: A --B41946 descr: 1 – venkyjack Jun 14 '17 at 11:02
  • Edit additional information into the question. Too hard to read in the comments. And note that there are fancy buttons for formatting at the top. – fancyPants Jun 14 '17 at 11:07
  • Possible duplicate of [Printing with sed or awk a line following a matching pattern](https://stackoverflow.com/questions/17908555/printing-with-sed-or-awk-a-line-following-a-matching-pattern) – Sundeep Jun 14 '17 at 11:35

4 Answers4

2

Two approaches:

-- awk approach:

awk '/^--B[0-9]+/{ r=NR; print }(NR-1)==r' file
  • /^--B[0-9]+/ - if the line starts with pattern

  • r=NR - hold the record number

  • (NR-1)==r - if it's the next line after the pattern line

To capture the following 2 lines after the pattern line - use this approach:

awk '/^--B[0-9]+/{ r=NR; print }(NR-1)==r || (NR-2)==r' file

-- GNU sed approach:

sed -n '/--B[0-9]*/{N;p;}' file
  • N - add a newline to the pattern space, then append the next line of input to the pattern space (GNU extension)

The output (for both approaches):

--B32934--
descr: X
--B20484
descr: A
--B41946
descr: 1
RomanPerekhrest
  • 88,541
  • 4
  • 65
  • 105
2

You may use the following awk command:

awk 'p{print;p=0}/^-/{print;p=1}' file

Explanation:

If the variable p is true, print the current line, set p back to 0 (false). If the line starts with a -, print the current line and set p to 1 (true) (in order to print the next line).

hek2mgl
  • 152,036
  • 28
  • 249
  • 266
  • Thank you. This works too, but if i need 2 lines instead of 1 what variable do i modify? – venkyjack Jun 14 '17 at 11:30
  • 1
    @venkyjack see https://stackoverflow.com/questions/17908555/printing-with-sed-or-awk-a-line-following-a-matching-pattern/17914105#17914105 for all sorts of things you can do... `awk '/^-/{p=3} p && p--'` would be one way for matching line and 2 afterwards – Sundeep Jun 14 '17 at 11:34
  • @Sundeep thank you, is there any way i can add a blank new line after each output? – venkyjack Jun 15 '17 at 09:41
  • Set the output record separator to two newlines: `awk 'p{print;p=0}/^-/{print;p=1}' ORS='\n\n' file` – hek2mgl Jun 15 '17 at 10:00
  • @hek2mgl thank you but this adds extra blank line between the B and the descr: , i just need between each set of B and descr: for eg: --B32934-- descr: X descr: Y descr: Z --B20484 descr: A descr: B descr: C – venkyjack Jun 15 '17 at 12:17
0

This might work for you (GNU sed):

sed '/^--B\S\+/!d;n' file

Delete any line that does not begin with --B followed by one or more non-space characters. Otherwise print that line and the following.

potong
  • 55,640
  • 6
  • 51
  • 83
0

Here's another solution with grep

grep -e '^--B[0-9]\+' --no-group-separator -A 1 file

outputs:

--B32934--
descr:     X
--B20484
descr:     A
--B41946
descr:     1
Josef
  • 232
  • 3
  • 12