0

I have a data2process.tempdata file with data in six columns as follows.

# Angle(deg)    D1      D2          D3          D4          D5
0.50    0.00E+00    0.00E+00    1.97E-10    3.94E-09    1.97E-10
1.00    0.00E+00    0.00E+00    1.70E-10    3.41E-09    1.70E-10
1.50    0.00E+00    0.00E+00    1.30E-10    2.59E-09    1.30E-10
2.00    0.00E+00    0.00E+00    9.49E-11    1.90E-09    9.49E-11
2.50    0.00E+00    0.00E+00    6.99E-11    1.40E-09    6.99E-11
3.00    0.00E+00    0.00E+00    5.27E-11    1.05E-09    5.27E-11
3.50    0.00E+00    0.00E+00    4.12E-11    8.23E-10    4.12E-11
4.00    0.00E+00    0.00E+00    3.33E-11    6.66E-10    3.33E-11
4.50    0.00E+00    0.00E+00    2.78E-11    5.56E-10    2.78E-11
5.00    0.00E+00    0.00E+00    2.37E-11    4.74E-10    2.37E-11

I want to multiply sixth column(D5) with 3.6E8 and find the first instance when the product becomes equal or less than 0.05. At that point, I want to save the corresponding value in the first column, print it and exit. In the (edited) data shown above, the first instance when the condition is met at 1.5 deg (1.3e-10*3.6e8=0.0468) but it holds true after that too. So echo $ maxangle should be 1.5, not 5.0 which here is the last entry which also satisfies the condition.

awk version is GNU Awk 5.0.1, API: 2.0 (GNU MPFR 4.0.2, GNU MP 6.2.0)

I was trying with the following awk commands.

maxangle=$(awk -v maxt=0.05; $6 *=3.6e8 '{if($6<=maxt){maxt=$6; maxa=$1}}END{print maxa ; exit} ' data2process.tempdata)

This gives an error *=3.6e8: command not found

maxangle=$(awk -v maxt=0.05 v6="$arg6"*3.6e8 '{if($v6<maxt){maxt=$1; maxa=$1}}END{print maxa ; exit} ' data2process.tempdata)

gives v6=*3.6e8 syntax error

maxangle=$(awk -v maxt=0.05 '{$6 = $6 * 3.6e8 ; if($6<=maxt){maxt=$1; maxa=$1}}  END{print maxa ;}' data2process.tempdata)
        echo $maxangle

gives me 5.0.

Thanks a lot for all your help. I am sure I can use all of it.

3
  • 1
    and on a side note exit seems a bit useless in END block.
    – Archemar
    Commented Apr 6, 2023 at 15:38
  • @Archemar, Yes. my apologies. I thought I edited it to reflect this, but first time jitters got me. Also, I thought I needed the exit to come out of the loop when I hit the first match. I am not sure how else I can do it with awk.
    – csnl
    Commented Apr 6, 2023 at 15:54
  • If that's what you want to do, you'd exit when the condition is true while reading the input, not in the END block which executes after all input has been read. No need to apologize, just edit your question to fix any mistakes and/or add any missing information.
    – Ed Morton
    Commented Apr 6, 2023 at 16:03

2 Answers 2

1

If you divide your 0.05 constant by 3.6E8 you'll have a value you can directly compare with field 6. This avoids any possibility of numeric underflow or loss of precision when comparing very large and very small values:

awk -v maxt=0.05 '
    BEGIN { tdash = maxt / 3.6E8 }
    NR>1 && $6 < tdash { print $1; exit }
' data2process.tempdata
1

OK I understand.

You want something like

awk -v maxt=0.05 '{t6 = $6 * 3.6e8 ;
        if(t6<=maxt){maxt=$1; maxa=$1}}
     END{print maxa ;}' data

You must be inside awk to multiply value fetched from file, so thing like v6="$arg6"*3.6e8 outside awk's code won't work.

which give 0

  • (with initials data) condition is met on first line, maxt and maxa are set 0, condition is never met again.

There is no need to store value (unless doing other computation within awk)

awk -v maxt=0.05 '$6 * 3.6e8 <= maxt {print $1 ; exit ;}' data

where

  • -v maxt=0.05 assign value to maxt
  • $6 * 3.6e8 <= maxt before { test for sucessfull condition (this is called a "pattern" in awk)
  • {print $1 ; exit ;} print searched value and exit. (this is called an "action" in awk)

and with new data give 1.5

3
  • Hi @archemar, Many thanks for your solution. I edited the question and changed the data format for clarity. In the earlier data, the first line had zero in the column of interest (as you pointed out), which I have now removed. In the current data, the condition is first met at the 3rd row, but also in all rows after. The solution I am looking for should print $1 from the 3rd row. To me, your solution gives the $1 value of the last row.
    – csnl
    Commented Apr 6, 2023 at 19:14
  • I think this one works. maxangle=$(awk -v maxt=0.05 '{$6 = $6 * 3.6e8 ; if($6<=maxt){maxt=$6; maxa=$1; print maxa ; exit} }' data2process.tempdata)
    – csnl
    Commented Apr 6, 2023 at 19:47
  • Both solutions work. Thanks for all the help.
    – csnl
    Commented Apr 14, 2023 at 11:45

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .