1

I am working on a shell script which has a lot of SED and AWK commands in it. Now, I am stuck up in a place where i couldn't proceed further.

For example :- If i run the below command. It prints the first column.

awk 'OFS="\t" {print $1;}' finename.txt

But, Is there a way to print a particular column using column name instead of column number. Guess there is no straight forward way to do it, But there should be some trick to do this.

Sample data(tab seperated)

  itemNumber  Price   Mango   Apple   Bannana
   112201      purchased   need-to-plan    purchased
   112202  55  yet-to-buy  yet-to-buy  purchased
   112202  67  need-to-plan    purchased   purchased
   112203  456 need-to-plan    need-to-plan    need-to-plan
   112203  33  need-to-plan    yet-to-buy  need-to-plan
   112204  456 need-to-plan    yet-to-buy  need-to-plan
   112204      yet-to-buy  purchased   need-to-plan
   112205  77  yet-to-buy  purchased   need-to-plan
   112205  99  yet-to-buy  purchased   yet-to-buy
   112206  0   yet-to-buy  purchased   yet-to-buy

2 Answers 2

4

Something like this?

awk -vcol=Price '(NR==1){colnum=-1;for(i=1;i<=NF;i++)if($(i)==col)colnum=i;}{print $(colnum)}' filename.csv

I should explain:

  • -v sets a variable, so with -vcol=Price I'm declaring the column that I'm looking for.
  • The (NR==1) selects the first line and the code after that searches through the column headers for the one we want to print.
  • Finally we print the column.

For multiple columns the approach is similar:

awk -F'\t' -vcols=fun,coming '(NR==1){n=split(cols,cs,",");for(c=1;c<=n;c++){for(i=1;i<=NF;i++)if($(i)==cs[c])ci[c]=i}}{for(i=1;i<=n;i++)printf "%s" FS,$(ci[i]);printf "\n"}' filename.csv
Sign up to request clarification or add additional context in comments.

6 Comments

You might want to add -F'\t' because the data seems to have some empty columns, so the default whitespace separator will not keep the column indexes.
Yes -F'\t' will do that. As usual you have lots of options. Tab separated input: BEGIN{IFS="\t"} output: BEGIN{OFS="\t"} and both BEGIN{FS="\t"}. But -F is the shortest of the lot so should win :-)
@MaxMurphy - Thats Awesome. Exactly what i was looking for.
@meuh - thanks for adding that. I was about to ask :-)
@MaxMurphy - Any idea how to print multiple columns with column name ?
|
0

Thanks @Max Murphy.

Personally needed awk -f' ' (so with space) and | column -t

In full:

awk -F' ' -vcols=pkts,bytes,source,destination '(NR==2){n=split(cols,cs,",");for(c=1;c<=n;c++){for(i=1;i<=NF;i++)if($(i)==cs[c])ci[c]=i}}{for(i=1;i<=n;i++)printf "%s" FS,$(ci[i]);printf "\n"}' | column -t

I used it to sort output of iptables -L -n -v --line-numbers on Debian

(Not a better answer to the question, but I think people appreciate a bit more elaboration.)

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.