Grep A Column Based On Column Name

I have a file with two columns separated by white space.

Dog        Cat
              fido       sneaky
             dopey      poptart
             ears       whisker
             barky      herd

Trying to list the words under the column named Dog. Tried a few variations of awk but can't get it to work. Any suggestions would be appreciated.

---------- Post updated at 03:29 PM ---------- Previous update was at 03:27 PM ----------

The code didn't paste properly let me try again.

Dog        Cat
fido       sneaky
dopey      poptart
ears       whisker
barky      herd

Maybe if you showed us what you tried, we could help you in your way, as I believe there are many solutions... and what was grep for? (here...)

1 Like

I got it to work!!!

awk -v header="Dog" '
BEGIN { FS=" "; c=0 }
NR == 1 { for (i=1;i<=NF;i++) { if ($i==header) { c=i }} }
NR > 1 && c>0 { print $c }
' dogs.log

vbe, I think it was the fear of the universe when you questioned me. Thanks!

2 Likes

Congratulations. Well done.

Here is a shell script that incorporates your awk code and an alternative that might help with issues you might run into in future endeavors.

If you save the following script in a file named tester :

#!/bin/ksh
echo 'Original code results:'
awk -v header="${1:-Dog}" '
BEGIN { FS=" "; c=0 }
NR == 1 { for (i=1;i<=NF;i++) { if ($i==header) { c=i }} }
NR > 1 && c>0 { print $c }
' dogs.log
echo "*** Exit status: $?"

printf '\nModified code results:\n'
awk -v header="${1:-Dog}" '
NR == 1 {
	for(i = 1; i <= NF; i++)
		if($i == header) {
			c = i
			next
		}
	printf("Header \"%s\" not found.\n", header)
	exit 1
}
{	print $c
}' dogs.log
echo "*** Exit status: $?"

and make it executable with:

chmod +x tester

and invoke it with no arguments:

./tester

you get:

Original code results:
fido
dopey
ears
barky
*** Exit status: 0

Modified code results:
fido
dopey
ears
barky
*** Exit status: 0

If you invoke it with an argument that is the name of one of the headings in dogs.log , for example:

./tester Cat
Original code results:
sneaky
poptart
whisker
herd
*** Exit status: 0

Modified code results:
sneaky
poptart
whisker
herd
*** Exit status: 0

And if you invoke it with an argument that does not match any of the header line values, for example:

./tester Horse

you get:

Original code results:
*** Exit status: 0

Modified code results:
Header "Horse" not found.
*** Exit status: 1

This was written and tested using a Korn shell, but will work with any shell that performs the basic parameter expansions required by the POSIX standards (such as ash , bash , dash , ksh , and zsh ).

Hi.

A code to work with this kind of data and requests is csvtool . This can be found in repositories for Debian (as noted below), Fedora 23 (Workstation), etc.:

#!/usr/bin/env bash

# @(#) s1       Demonstrate manipulation of CSV data.
# csvtool, Debian repository, and:
# https://github.com/Chris00/ocaml-csv
#
# align: http://kinzler.com/me/align/

# Utility functions: print-as-echo, print-line-with-visual-space, debug.
# export PATH="/usr/local/bin:/usr/bin:/bin"
LC_ALL=C ; LANG=C ; export LC_ALL LANG
pe() { for _i;do printf "%s" "$_i";done; printf "\n"; }
pl() { pe;pe "-----" ;pe "$*"; }
em() { pe "$*" >&2 ; }
db() { ( printf " db, ";for _i;do printf "%s" "$_i";done;printf "\n" ) >&2 ; }
db() { : ; }
C=$HOME/bin/context && [ -f $C ] && $C csvtool align

FILE=${1-data1}

pl " Input data file $FILE:"
cat $FILE

pl " Results:"
sed 's/  */,/g' $FILE |
tee f1 |
csvtool namedcol Cat,Dog - |
align -s /,

exit 0

producing:

$ ./s1

Environment: LC_ALL = C, LANG = C
(Versions displayed with local utility "version")
OS, ker|rel, machine: Linux, 3.16.0-4-amd64, x86_64
Distribution        : Debian 8.4 (jessie) 
bash GNU bash 4.3.30
csvtool - ( /usr/bin/csvtool, 2014-08-06 )
align 1.7.0

-----
 Input data file data1:
Dog        Cat
fido       sneaky
dopey      poptart
ears       whisker
barky      herd

-----
 Results:
Cat     Dog
sneaky  fido
poptart dopey
whisker ears
herd    barky

The script could be modified to allow requests to come in from the command line as well.

Best wishes ... cheers, drl