Print the column content based on the header

i have a input of csv file as below but the sequence of column get changed.
I,e it is not necessary that name comes first then age and rest all, it may vary.

name,age,marks,roll,section
kevin,25,80,456,A
Satch,23,56,789,B
Meena,24,78,H245,C
 

So i want to print that column entires which contains 'name' at the top.
i,e i want the output should be

Kevin
Satch
Meena

awk -F"," ' /name/ { for (i=1;i<=NF;i++) if ($i=="name") idx=i} $0 !~ /name/ { print $idx} ' file
1 Like

Not tested but this should work

 
l=wc -l
l=`echo $l -1 |bc`
for name in `tail -$l $file|awk '{print $1}'|`
do
 tmp=`echo name|grep -Po '^[a-z]+$'`
 if [ "$tmp" = "$name" ]
  echo $name
 fi
done

way is simple. i tried reading file using tail (except the first line) and passed to awk. read the first column and using grep i tried matching it with a name formate which will contain charecters in range "a-z". it if matches -o opetion will return the matched part.
if it's name then it should return the complete name and tmp and name variable should match.
Hope i'm clear

Hey Fundix,Thank you ..it worked fine.

But i want to keep name in a variable

var="name"
awk -F"," ' /$var/ { for (i=1;i<=NF;i++) if ($i=="$var") idx=i} $0 !~ /$var/ { print $idx} ' filename

But it is not giving the output..Could you pls tell me know how i will use a variable here.

Try:

awk -F, '$0 ~ ",?" var ",?" {for(i=1;i<=NF;i++) if($i == var) idx=i; next}
{print $idx}' var=name filename

You can use -v to pass vars to awk :

awk -v var="name" -F"," ' /var/ { for (i=1;i<=NF;i++) if ($i==var) idx=i} $0 !~ /var/ { print $idx} ' file

That will not work. It will try to match (or not) the string "var".

Sorry, not well awake this morning, answering without testing :wink:

The following works fine now :

awk -v var="name" -F"," ' $0 ~ var { for (i=1;i<=NF;i++) if ($i==var) idx=i} $0 !~ var { print $idx} ' file

I'm a little confused as to why most of the scripts that have been proposed in this thread look for a column containing the heading on any line that contains the heading (instead of just looking at the first line). I'm also a little surprised that none of them report an error if the requested column header is not found. This isn't a one-liner, but I hope you'll find it useful:

#!/bin/ksh
IAm=${0##*/}
if [ $# -ne 2 ]
then    printf "Usage: %s input_file column_heading\n" "$IAm" >&2
        exit 1
fi
ef=_"$IAm$$"
if [ ! -f "$1" ] || [ ! -r "$1" ]
then
    printf "%s: input_file \"%s\" must be a readable regular file.\n" \
                "$IAm" "$1" >&2
        exit 2
fi
if ! awk -F, -v ch="$2" -v IAm="$IAm" -v ef="$ef" '
FNR == 1 {
        for(i = 1; i <= NF; i++)
                if($i == ch) break
        if(i > NF) {
                printf("%s: column_heading %s not found\n", IAm, ch) > ef
                exit 3
        }
        next
}
{       print $i}' "$1"
then    cat "$ef" >&2
        rm -f "$ef"
        exit 3
fi

As always, if you're using a Solaris/SunOS system, use /usr/xpg4/bin/awk , /usr/xpg6/bin/awk , or nawk instead of awk .

I use the Korn shell, but any shell that recognizes the variable expansions defined by the POSIX standards and the Single UNIX Specifications (e.g., bash) will also work.

To use it, save the above script in a file (e.g., getf ), make it executable:

chmod +x getf

and invoke it with two arguments (a pathname of your input file and the column heading for the field you want to get out of the file). For example, if the input provided in the 1st message in this thread is stored in a file named input.csv , the command:

getf input.csv marks

produces the output:

80
56
78

I tried the above two ways...but i m getting below error.

awk: syntax error near line 1
awk: bailing out near line 1

What OS are you using?

Did you notice the comment in my last posting: As always, if you're using a Solaris/SunOS system, use /usr/xpg4/bin/awk , /usr/xpg6/bin/awk , or nawk instead of awk .

A simple Perl workaround using a 2 pass reading the file.
The line "name,xxx,xxx" may be anywhere in the file (top, middle, tail)
The 1st pass detects the index of the requested field, the 2nd one displays the corresponding field on the other lines :

#!/usr/bin/perl -w
use strict;

my $cur_dir = $ENV{PWD};
my $filename = "$cur_dir/$ARGV[0]";

my ($record,@fields,$index);

open(FILE,"<$filename") or die"open: $!";
while( defined( $record = <FILE> ) ) {
  chomp $record;
  if ( $record =~ $ARGV[1] ) {
    @fields=split(/,/,$record);
    ($index) = grep { $fields[$_] eq $ARGV[1] } 0..$#fields;
    last
  }
}
close(FILE);

open(FILE,"<$filename") or die"open: $!";
while( defined( $record = <FILE> ) ) {
  chomp $record;
  if ( $record !~ $ARGV[1] ) {
    @fields=split(/,/,$record);
    print "$fields[$index]\n";
  }
}
close(FILE);

examples :

%./file018.pl file018 name
kevin
Satch
Meena
%./file018.pl file018 section
A
B
C

Now that I'm awake this morning, I do see that there was a copy and paste error that misplaced a "then" in my script. I fixed that in place in message #9 in this thread a few minutes ago. But, given the error message you reported, I'm still assuming that you're using a Solaris system and need to change the line that starts with "awk" to instead start with "/usr/xpg4/bin/awk".