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