user400480
user400480

Reputation: 573

How to reverse order of fields using AWK?

I have a file with the following layout:

123,01-08-2006
124,01-09-2007
125,01-10-2009
126,01-12-2010

How can I convert it into the following by using AWK?

123,2006-08-01
124,2007-09-01
125,2009-10-01
126,2009-12-01

Upvotes: 4

Views: 11216

Answers (4)

Andrew
Andrew

Reputation: 3061

Didn't read the question properly the first time. You need a field separator that can be either a dash or a comma. Once you have that you can use the dash as an output field separator (as it's the most common) and fake the comma using concatenation:

awk -F',|-' 'OFS="-" {print $1 "," $4,$3,$2}' file

Upvotes: 4

paxdiablo
paxdiablo

Reputation: 881463

Unfortunately, I think standard awk only allows one field separator character so you'll have to pre-process the data. You can do this with tr but if you really want an awk-only solution, use:

pax> echo '123,01-08-2006
124,01-09-2007
125,01-10-2009
126,01-12-2010' | awk -F, '{print $1"-"$2}' | awk -F- '{print $1","$4"-"$3"-"$2}'

This outputs:

123,2006-08-01
124,2007-09-01
125,2009-10-01
126,2010-12-01

as desired.

The first awk changes the , characters to - so that you have four fields separated with the same character (this is the bit I'd usually use tr ',' '-' for).

The second awk prints them out in the order you specified, correcting the field separators at the same time.

If you're using an awk implementation that allows multiple FS characters, you can use something like:

gawk -F ',|-' '{print $1","$4"-"$3"-"$2}'

Upvotes: 1

ghostdog74
ghostdog74

Reputation: 342373

Pure awk

awk -F"," '{ n=split($2,b,"-");$2=b[3]"-"b[2]"-"b[1];$i=$1","$2 } 1' file

sed

sed -r 's/(^.[^,]*,)([0-9]{2})-([0-9]{2})-([0-9]{4})/\1\4-\3-\2/' file
sed 's/\(^.[^,]*,\)\([0-9][0-9]\)-\([0-9][0-9]\)-\([0-9]\+\)/\1\4-\3-\2/' file

Bash

#!/bin/bash

while IFS="," read -r a b
do
  IFS="-"
  set -- $b
  echo "$a,$3-$2-$1"
done <"file"

Upvotes: 2

Bevor
Bevor

Reputation: 8605

If it doesn't need to be awk, you could use Perl too:

$ perl -nle 'print "$1,$4-$3-$2" while (/(\d{3}),(\d{2})-(\d{2})-(\d{4})\s*/g)' < file.txt

Upvotes: 0

Related Questions