lacrosse1991
lacrosse1991

Reputation: 3162

how can I supply bash variables as fields for print in awk

I currently am trying to use awk to rearrange a .csv file that is similar to the following:

stack,over,flow,dot,com

and the output would be:

over,com,stack,flow,dot

(or any other order, just using this as an example)

and when it comes time to rearrange the csv file, I have been trying to use the following:

first='$2'
second='$5'
third='$1'
fourth='$3'
fifth='$4'

awk -v a=$first -v b=$second -v c=$third -v d=$fourth -v e=$fifth -F '^|,|$' '{print $a,$b,$c,$d,$e}' somefile.csv

with the intent of awk/print interpreting the $a,$b,$c,etc as field numbers, so it would come out to the following:

{print $2,$5,$1,$3,$4}

and print out the fields of the csv file in that order, but unfortunately I have not been able to get this to work correctly yet. I've tried several different methods, this seeming like the most promising, but unfortunately have not been able to get any solution to work correctly yet. Having said that, I was wondering if anyone could possibly give any suggestions or point out my flaw as I am stumped at this point in time, any help would be much appreciated, thanks!

Upvotes: 1

Views: 836

Answers (3)

Ed Morton
Ed Morton

Reputation: 203368

You already got the answer to your specific question but have you considered just specifying the order as a string instead of each individual field? For example:

order="2 5 1 3 4"

awk -v order="$order" '
   BEGIN{ FS=OFS=","; n=split(order,a," ") }
   { for (i=1;i<n;i++) printf "%s%s",$(a[i]),OFS; print $(a[i]) }
' somefile.csv

That way if you want to add/delete fields or change the order you just trivially rearrange the numbers in the first line instead of having to mess with a bunch of hard-coded variables, etc.

Note that I changed your FS as there was no need for it to be that complicated. Also, you don't need the shell variable, "order",you could just populate the awk variable of the same name explicitly, I just started with the shell variable since you had started with shell variables so maybe you have a reason.

Upvotes: 0

perreal
perreal

Reputation: 97948

Another way with a shorter example:

aa='$2'
bb='$1'
cc='$3'

awk -F '^|,|$' "{print $aa,$bb,$cc}" somefile.csv

Upvotes: 1

Jonathan Leffler
Jonathan Leffler

Reputation: 753675

Use simple numbers:

first='2'
second='5'
third='1'
fourth='3'
fifth='4'

awk -v a=$first -v b=$second -v c=$third -v d=$fourth -v e=$fifth -F '^|,|$' \
     '{print $a, $b, $c, $d, $e}' somefile.csv

Upvotes: 1

Related Questions