3
    MaxVal  MinVal  AvgVal
    3.8959  0.795   2.249071429
    3.8416  0.7761  2.280848
    3.896   0.7949  2.221309804
    3.8727  0.7746  2.252477966
    3.8953  0.7957  2.225252

Suppose I want to extract the column which has heading "AvgVal". How can I do it using sed/grep commands. Actual file has more than 1000 columns.

  • If the columns are tab separated you can use awk '{print $NF}'. NF in awk will print the last column. In this case you could also awk '{print $3}' – Valentin Bajrami Apr 1 '17 at 11:09
  • Actually the above file is just an example. They are tab separated and contains more than 1000 columns. I need to extract may be 20 or 30 columns on the basis of text matching. – jyoti Apr 1 '17 at 11:39
1
perl -pale '
   $. == 1 and ($idx) = grep { $F[$_] eq "AvgVal" } 0..$#F;
   $_ = $F[$idx];
' yourfile

We first get a lock on the column number that we are seeking to print, by going through the fields of record 1 and use that then to print the data.

  • Thanks. It is nicely working for the given data. However, if I need to print the column with heading "Average Bonding Information Content (Order 0)" or anything similar it is printing only DBID. How can I make it to work for the columns with different headings? – jyoti Apr 1 '17 at 11:26
  • What is DBID? You should not incrementally change the requirements. Instead you should have been upfront with the kind of data you intend to work on rather than tell us piecemeal and then incrementally increase the requirements. – user218374 Apr 1 '17 at 15:55
1

Try this. Searches the first line for the field you're wanting (AvgVal in this case), and store the column number in variable a. And then for each line set $0 to the column we want. As the default behaviour is to print $0, this then achieves the goal.

$ awk 'NR==1{while($++a!="AvgVal");}{$0=$a}1' filename
AvgVal
2.249071429
2.280848
2.221309804
2.252477966
2.225252
$
0

Another approach using shell script :

#!/bin/sh

filename=file.txt
search="AvgVal"

column_num=`awk -F' ' '{ for (i = 1; i <= NF; ++i) print i, $i; exit } ' $filename | grep $search | awk '{ print $1 }'`
awk -v x=$column_num '{ print $x }' $filename
0

With AWK, this will scan all the field till to find the Header you want and then will print the column found:

$ a=$'MaxVal\tMinVal\tAvgVal\n3.8959\t0.795\t2.249071429\n3.8416\t0.7761\t2.280848'

$ echo "$a"
MaxVal  MinVal  AvgVal
3.8959  0.795   2.249071429
3.8416  0.7761  2.280848

$ awk 'NR==1{for (i=1;i<=NF;i++) if ($i=="AvgVal") {a=i;break}}{print $a}' <<<"$a"
AvgVal
2.249071429
2.280848

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.