Search code examples
awkscientific-notation

Use awk to remove scientific notation in a column


While I'm sure that this has been answered somewhere, I can't find where, so I'm very sorry if this is a repeat. Here we go.

I have a file (really, I have many files) that has X, Y, and Z data points separated by spaces into three columns. I'm trying to 3d plot these with GNUplot, which, sadly, doesn't seem very pleased with scientific notation. Now, I can sed my way to (A*10**B) notation instead of (AE+B) notation, but GNUplot still doesn't recognize it.

I know I can convert from scientific notation with printf "%.5f" (I think five digits would be just fine), but I can't find how to format my input so that I can apply this to multiple columns, or, better yet, how to control the format for each column. I can convert a single value:

echo ""|awk '{printf "%.5f", $2}' k11edit.dat

but I can't get it to handle multiple columns, nor even to maintain a space between values (a tab would be just fine, too; I'm not partial to a single space).

Here are a couple lines of my file:

0.995 8.1584E-004 -0.17051415E+01
0.995 8.8934E-004 -0.17053282E+01
0.995 9.6284E-004 -0.17055150E+01
0.995 1.0363E-003 -0.17057018E+01
0.995 1.1098E-003 -0.17058886E+01
0.995 1.1833E-003 -0.17060754E+01
0.995 1.2568E-003 -0.17062623E+01
0.995 1.3303E-003 -0.17064493E+01
0.995 1.4038E-003 -0.17066362E+01
0.995 1.4773E-003 -0.17068232E+01
0.995 1.5508E-003 -0.17070103E+01
0.995 1.6243E-003 -0.17071973E+01
0.995 1.6978E-003 -0.17073846E+01

Yes, I'm aware that the first column doesn't change in these few lines, but it does further down (the file is ~30,000 lines long, so I thought a few lines would suffice here).

Could you help me out?


Solution

  • Without seeing your expected output it's a guess but is this what you want:

    $ awk '{for (i=1;i<=NF;i++) printf "%.5f%s", $i, (i<NF?OFS:ORS)}' file
    0.99500 0.00082 -1.70514
    0.99500 0.00089 -1.70533
    0.99500 0.00096 -1.70551
    0.99500 0.00104 -1.70570
    0.99500 0.00111 -1.70589
    0.99500 0.00118 -1.70608
    0.99500 0.00126 -1.70626
    0.99500 0.00133 -1.70645
    0.99500 0.00140 -1.70664
    0.99500 0.00148 -1.70682
    0.99500 0.00155 -1.70701
    0.99500 0.00162 -1.70720
    0.99500 0.00170 -1.70738
    

    If you want a different format for each field:

    $ awk 'BEGIN{split("%.3f %.7f %.4f",fmt)}
           {for (i=1;i<=NF;i++) printf fmt[i]"%s", $i, (i<NF?OFS:ORS)}' file
    0.995 0.0008158 -1.7051
    0.995 0.0008893 -1.7053
    0.995 0.0009628 -1.7055
    0.995 0.0010363 -1.7057
    0.995 0.0011098 -1.7059
    0.995 0.0011833 -1.7061
    0.995 0.0012568 -1.7063
    0.995 0.0013303 -1.7064
    0.995 0.0014038 -1.7066
    0.995 0.0014773 -1.7068
    0.995 0.0015508 -1.7070
    0.995 0.0016243 -1.7072
    0.995 0.0016978 -1.7074