Printing Only Part of a grep Match
By Adrian Sutton
It’s not uncommon to want to find a particular line in a file and print just a part of it. For example, if we wanted to find the total memory on a machine we could use:
grep '^MemTotal:' /proc/meminfo |
sed -e 's/^MemTotal:\s*\([0-9]*\).*/\1/'
Which does the job but duplicates a bunch of the matching regex. If you’re using a reasonably recent gnu grep, you can use it’s support for perl regex syntax and the \K operator:
grep -Po '^(MemTotal:\s*)\K[0-9]*' /proc/meminfo
The -P is for perl regex, and the o option causes grep to output only what is matched. You can see though that we’re actually matching the MemTotal: at the start of the line yet somehow it doesn’t wind up in the output. That’s the magic of \K which excludes the token immediately prior to it from the matched text (without rewinding the stream and attempting a different match for that text).
Update
Alexandre Niveau emailed me to point out that in this particular case (and probably most others where I’d be tempted to use \K with grep) grep is completely superfluous and we can just use sed with the -n flag:
sed -n -e 's/^MemTotal:\s*\([0-9]*\).*/\1/p' /proc/meminfo
The -n disables automatic printing of lines and the ‘p’ at the end of the regex prints the matching lines. Definitely good to know – thanks Alexandre.