1

I use

cmd | egrep 'ID|Value'

andget the following output on my command line:

    ID: 2
Value: 21
    ID: 1
Value: 25
    ID: 1
Value: 22
    ID: 3
Value: 56
    ID: 1
Value: 23
    ID: 2
Value: 50
    ID: 2
Value: 56
    ID: 3
Value: 11
    ID: 3
Value: 26

I would like to filter it by one special ID. But when I use:

egrep 'ID: 1|Value'

It will show the same output with just ID 1, but the Values of all IDs.

I already read about awk, sed and regex, but i can't find anything that would really help me, but I'm also not that deep into that.

Someone can suggest an idea, or tell me that it's the wrong way to approach it and I should do it differently and how?

Output as wanted:

    ID: 1
Value: 25
    ID: 1
Value: 22
    ID: 1
Value: 23
Inian
  • 80,270
  • 14
  • 142
  • 161
AdrianL
  • 335
  • 2
  • 18

5 Answers5

8

Just tell grep to print the matching line together with the next one:

$ grep -A1 'ID: 1$' file
    ID: 1
Value: 25
    ID: 1
Value: 22
--
    ID: 1
Value: 23

From man grep:

-A NUM, --after-context=NUM

Print NUM lines of trailing context after matching lines. Places a line containing a group separator (--) between contiguous groups of matches. With the -o or --only-matching option, this has no effect and a warning is given.

Note the usage of $ to mark the end of the line. Otherwise, this would match lines line ID: 1323423423.

If you don't like the -- appearing in between matches, get rid of it with:

grep -A1 --no-group-separator 'ID: 1$' file
#        ^^^^^^^^^^^^^^^^^^^^
fedorqui
  • 275,237
  • 103
  • 548
  • 598
6

For other tags:

awk

awk '/ID: 1$/ {print; getline; print}'

sed, very similar

sed -n '/ID: 1$/ {p;n;p}'

and bash

while read line; do if [[ $line == *"ID: 1" ]]; then echo "$line"; read line; echo "$line"; fi; done
glenn jackman
  • 238,783
  • 38
  • 220
  • 352
5

Another simple script using awk

awk '/ID: 1/{line[NR]; line[NR+1]}; NR in line' file

will give output as:-

    ID: 1
Value: 25
    ID: 1
Value: 22
    ID: 1
Value: 23

NR is a special awk variable which stores the record number. All we do is match a pattern, and get the Nth and N+1th record in the line to print in the file and ensure that the record to be printed is well within the max range in that line (NR in line).

Inian
  • 80,270
  • 14
  • 142
  • 161
  • 1
    This is first time I have seen this kind of use for `NR`... +1 for creativity. Hopefully I will remember it... – anishsane Jun 14 '16 at 15:17
1

A solution using GNU sed (sometimes available as gsed on BSD systems):

$ sed -n -e '/ID: 1/,+1p' data.in
    ID: 1
Value: 25
    ID: 1
Value: 22
    ID: 1
Value: 23

Explanation: The sed script "/ID: 1/,+1p" applies the p (print) command on all lines of the input in the range /ID: 1/ to +1, i.e every line matching the regular expression "ID: 1" and "one line further along" (the +n address is a GNU extension to the POSIX standard).

The -n flag to sed ensures that nothing other than what the p command prints gets printed ("suppress automatic printing of pattern space").

Kusalananda
  • 14,885
  • 3
  • 41
  • 52
0

This might work for you (GNU sed):

sed '/ID: 1$/!d;n' file

Delete any line that is not ID: 1 and then print it and the next.

potong
  • 55,640
  • 6
  • 51
  • 83