Ivan
Ivan

Reputation: 7746

awk to transpose lines of a text file

A .csv file that has lines like this:

20111205 010016287,1.236220,1.236440

It needs to read like this:

20111205 01:00:16.287,1.236220,1.236440

How do I do this in awk? Experimenting, I got this far. I need to do it in two passes I think. One sub to read the date&time field, and the next to change it.

awk -F, '{print;x=$1;sub(/.*=/,"",$1);}' data.csv

Upvotes: 1

Views: 100

Answers (2)

chaos
chaos

Reputation: 9282

Use that awk command:

echo "20111205 010016287,1.236220,1.236440" | \
awk -F[\ \,] '{printf "%s %s:%s:%s.%s,%s,%s\n", \
$1,substr($2,1,2),substr($2,3,2),substr($2,5,2),substr($2,7,3),$3,$4}'

Explanation:

  • -F[\ \,]: sets the delimiter to space and ,
  • printf "%s %s:%s:%s.%s,%s,%s\n": format the output
  • substr($2,0,3): cuts the second firls ($2) in the desired pieces

Or use that sed command:

echo "20111205 010016287,1.236220,1.236440" | \
sed 's/\([0-9]\{8\}\) \([0-9]\{2\}\)\([0-9]\{2\}\)\([0-9]\{2\}\)\([0-9]\{3\}\)/\1 \2:\3:\4.\5/g'

Explanation:

  • [0-9]\{8\}: first match a 8-digit pattern and save it as \1
  • [0-9]\{2\}...: after a space match 3 times a 2-digit pattern and save them to \2, \3 and \4
  • [0-9]\{3\}: and at last match 3-digit pattern and save it as \5
  • \1 \2:\3:\4.\5: format the output

Upvotes: 2

Ed Morton
Ed Morton

Reputation: 203522

sed is better suited to this job since it's a simple substitution on single lines:

$ sed -r 's/( ..)(..)(..)/\1:\2:\3./' file
20111205 01:00:16.287,1.236220,1.236440

but if you prefer here's GNU awk with gensub():

$ awk '{print gensub(/( ..)(..)(..)/,"\\1:\\2:\\3.","")}' file
20111205 01:00:16.287,1.236220,1.236440

Upvotes: 0

Related Questions