Extract a field in space delimited data

From raju

Task

The task here is to extract a field in space separated data. Consider for example

% dpkg -l \*gcc\* | grep ^ii | cut -c1-72
ii  gcc                4:6.1.1-1    amd64        GNU C compiler
ii  gcc-6              6.2.0-6      amd64        GNU C compiler
ii  gcc-6-base:amd64   6.2.0-6      amd64        GCC, the GNU Compiler C
ii  gcc-6-base:i386    6.2.0-6      i386         GCC, the GNU Compiler C
ii  gcc-6-doc          6.1.0-1      all          documentation for the G
ii  gcc-doc            5:6.1.0-1    amd64        documentation for the G
ii  gcc-doc-base       6.1.0-1      all          several GNU manual page
ii  libgcc-6-dev:amd64 6.2.0-6      amd64        GCC support library (de
ii  libgcc1:amd64      1:6.2.0-6    amd64        GCC support library
ii  libgcc1:i386       1:6.2.0-6    i386         GCC support library

We want to extract the packages listed in the second column. So the desired output is

gcc
gcc-6
gcc-6-base:amd64
gcc-6-base:i386
gcc-6-doc
gcc-doc
gcc-doc-base
libgcc-6-dev:amd64
libgcc1:amd64
libgcc1:i386

The challenge here is to treat multiple spaces as one when extracting a single field.

Solution

This can be done in two ways: awk and cut. The advantage of awk is that it handles multiple spaces seamlessly. But with cut one has to suppress multiple spaces beforehand.

Using awk

% dpkg -l \*gcc\* | grep ^ii | cut -c1-72 | awk {'print $2'}
gcc
gcc-6
gcc-6-base:amd64
gcc-6-base:i386
gcc-6-doc
gcc-doc
gcc-doc-base
libgcc-6-dev:amd64
libgcc1:amd64
libgcc1:i386

Using cut

% dpkg -l \*gcc\* | grep ^ii | cut -c1-72 | tr -s ' ' | cut -f 2 -d ' '
gcc
gcc-6
gcc-6-base:amd64
gcc-6-base:i386
gcc-6-doc
gcc-doc
gcc-doc-base
libgcc-6-dev:amd64
libgcc1:amd64
libgcc1:i386