Floating point to integer in variable length lines

Hi !

I'm looking for a way to transform certain floating point numbers in a one-line, variable length file to integers.

I can do this in a crude way with sed :

sed -e 's/0\.\([1-9][0-9]\)[0-9]:/\1:/g' -e 's/0\.0\([0-9]\)[0-9]:/\1:/g' -e 's/1\.000:/100:/g' myfile 

... but this doesn't handle the rounding correctly.

I'm not very familiar with awk or perl, which are more adapted to arithmetics than sed.
So I can use them to look for my number to replace, but how to get the arithmetics done ?

So far, I can recognize the numbers to change :

awk  '{gsub(/)[0-9]+\.[0-9]+:/,")boot:")};1' myfile

or :

perl -pe 's/\)([0-9]+\.[0-9]+):/\)$1*100:/g' myfile

The floating point number to replace is always between a ")" and a ":" ; other numbers should be left unchanged.
So in the awk command, can I replace "boot" with an arithmetic operation ?
In the perl command, how to do the arithmetics and not just printing "0.100*100" ?

Just to give an example of the file, but they can be much more complicated :

(X1.13:0.39456,X1:0.00014,(Y3:0.01259,(XX:0.18846,YK3:0.14006)1.000:0.73816)0.758:0.01603);

The numbers to be changed are "1.000" and "0.758".

Thanks for reading !
jos

Not sure how complex the other lines are but with the given example this should work:

awk -F")" '{
  for(i=2;i<NF;i++){
    f=s=$i
    sub(":.*","",f)
    sub(".*:","",s)
    f=sprintf("%d",f+=f<0?-0.5:0.5)
    sub($i,f ":" s)
  }
}1' file

Almost !!

Unfortunately, the files can be much more complex :

(X20Y5:0.00598,XFE925AG01BP13V:0.00014,((X20Y4:0.00015,((((((X_5429Y1:0.0,X135Y5:0.0,X_413Y5:0.0):0.00014,(X_413Y2:0.00014,(XFF3TYA401DUH5R:0.01977,XFE925AG01CQHOO:0.00014)0.002:0.00606)1.000:0.01556)1.000:0.00010,X20Y13:0.00014)0.706:0.01362,XFF3TYA401EFQJT:0.01526)0.894:0.02751,(((((X_XFCNODTR01B4F9S:0.00014,(((X_534Y3:0.0,X141Y5:0.0):0.00014,X135Y4:0.04083)0.940:0.00014,(((X8682Y1:1.47181,(X20Y6:0.00014,((X_2820Y1:0.06120,(XFE925AG01DGHOS:0.02006,(XFF3TYA401CZLA2:0.00014,(X20Y7:0.00015,X_XFCQ9HMJ02F3SXN:0.34874)0.817:0.06106)0.370:0.00016)0.681:0.04071)0.773:0.06240,(X7334Y1:0.00015,((X_11012Y1:0.00014,XFE925AG01CB5T7:0.12961)0.928:0.13351,(X135Y1:0.04343,(X_413Y1:0.00014,X_413Y3:0.02821)0.758:0.02294)0.958:0.13863)0.768:0.02126)0.989:0.25127)0.647:0.16916)0.904:1.72195)0.894:1.02365,((XFE925AG01C1B14.1:0.03105,(XFE925AG01A2A19.1:0.22512,(X20Y1:0.00014,(((X7467Y1:0.0,X_413Y6:0.0):0.02530,X135Y2:0.02571)0.318:0.00015,(((X141Y1:0.01394,XFEYVE6F02HU6WN:0.02870)0.834:0.04168,X20Y3:0.08003)0.911:0.05329,X20Y8:0.00014)0.877:0.01481)0.823:0.01872)0.922:0.00016)0.491:0.10360)0.996:3.51313,(X5693Y1:0.06043,((X_10186Y1:0.00014,XFE925AG01BVRXL:0.12881)1.000:0.42997,X_534Y1:0.00014)0.619:0.05331)0.893:2.20476)0.634:0.40367)0.936:0.00016,X_534Y4:0.00014)0.868:0.02525)0.009:0.00019)0.000:0.01721,(X135Y3:0.01329,(X141Y3:0.00014,X_534Y2:0.00016)0.776:0.00016)0.753:0.01072)0.751:0.01278,X20Y9:0.00015)0.711:0.02725,XFE925AG01BZXI5:0.06080)0.000:0.00014,X141Y2:0.00014)0.000:0.00014)0.296:0.00016,(X20Y10:0.00015,XFF3TYA401C9256:0.00014)0.928:0.02727)0.511:0.00016)0.900:0.00015,((X141Y4:0.01346,((((((X_XFEYVE6F02GNAZK:0.00014,((X427Y1:0.0,X1374Y1:0.0,X_2296Y1:0.0,X_2492Y1:0.0):0.00014,(XFE925AG01DV2FE.1:0.30844,X3022Y1:0.00014)0.779:0.00015)1.000:0.00012)0.240:0.00787,(X5991Y1:0.00014,(X_XFCNODTR01CPWAD:0.00014,X_XFCQ9HMJ02G5NCQ:0.24167)0.981:0.16340)0.953:0.11546)0.853:0.08559,X2249Y1:0.11962)0.981:0.20467,X_XFCNODTR01ESRDF:0.03636)0.763:0.03322,X_XFEYVE6F02HSKXD:0.14729)0.674:0.01770,X_SdF_FCPQ3KJ02J4WTR:0.06413)0.167:0.03671)0.720:0.00014,(X20Y14:0.02719,(X_413Y4:0.0,X3439Y1:0.0):0.00014)0.006:0.00015)0.850:0.01368)1.000:0.00754);

Some "):" don't have a number between them, so I included a test for matches :

awk -F")" '{
for(i=1;i<NF;i++){
if( match($i, /^[0-9]+\.[0-9]+:/) ) { 
f=s=$i
    sub(":.*","",f)
    sub(".*:","",s)
    f=sprintf("%d",f=(f*100)+0.5)
    sub($i,f ":" s)
}
  }
}1' testfile

but this gives the following error :

awk: cmd. line:7: (FILENAME=testfile FNR=1) fatal: Unmatched ( or \(: /0.894:0.02751,(((((X_XFCNODTR01B4F9S:0.00014,(((X_534Y3:0.0,X141Y5:0.0/

???

---------- Post updated at 04:02 PM ---------- Previous update was at 02:23 PM ----------

Got it !
One needs to prevent awk from interpreting the parenthesis in the input file, as indicated here :
Re: Passing shell variable with special chars to AWK

Thanks, Franklin52 !

If anyone needs it :

awk -F")" '{
for(i=1;i<NF;i++){
    if( $i ~ /^[0-9]+\.[0-9]+:/ ) { 
    f=s=$i
    p=$i
    gsub(/./,"[&]",p)      
    sub(":.*","",f)
        sub(".*:","",s)
        f=sprintf("%d",f=(f*100)+0.5)
    sub(p,f ":" s)
    }
  }
}1' testfile 

You're welcome, well done and good luck!

Regards