Here is a solution with awk
. It separates first four characters and rest of the 2nd column into two variables and print them.
]$ awk '{s=substr($2,1,4)}{g=substr($2,5,length($2))}{print $1,s,g}' file.txt
1A THIS ISATEST
1B THAT ISATEST
You have the fields in the right order, but your first print statement adds a newline (Output Record Separator), so your data's there, but just wrapped unexpectedly.
The second issue is that you're telling printf to use a width of 4; that includes the decimal point and the two digits after it, leaving only one for the leading digit and none for any padding. Try using 5 as the width, so that your data is padded up to four total numbers. If you want 4 digits before the decimal point, then change the width to 7 instead.
This is the shortest change I made from your program to something that outputs what I think you want:
awk -F"|" '{
format = "%05.2f,%05.2f,%05.2f";
print $1","$2","$3","$4"," sprintf(format, $5,$6,$7)}' filename
I combined multiple { }
blocks into one, and also combined the print statements into one.
If I was to write your awk statement from scratch, I might do something like this:
awk -v FS=\| -v OFS=, '{
$5=sprintf("%05.2f", $5);
$6=sprintf("%05.2f", $6);
$7=sprintf("%05.2f", $7);
print $1,$2,$3,$4,$5,$6,$7}' filename
It explicitly sets the input Field Separator, the Output Field Separator, explicitly converts each of the fields on its own, then prints the desired fields, with the OFS separating them.
Best Answer
A locale-independent solution with manual formatting
This should work on any POSIX-compatible OS regardless of the locales installed.
A solution that uses
printf
and the en_US locale.The
printf
sequence%'d
prints a decimal integer formatted with the current locale's thousands separator.