Search code examples
awkwhile-loopconky

Using an awk while-loop in Conky


I'm struggling with a while() loop in a Conky script.

Here's what I want to do :

I'm tunneling a command output to awk, extracting and formatting data.

The problem is : the output could contain 1 to n sections, and I want to get values from each one of them.

Here's the output sent to awk :

1) -----------
   name: wu_1664392603_228876_0
   WU name: wu_1664392603_228876
   project URL: https://boinc.loda-lang.org/loda/
   received: Thu Oct  6 15:31:40 2022
   report deadline: Thu Oct 13 15:31:40 2022
   ready to report: no
   state: downloaded
   scheduler state: scheduled
   active_task_state: EXECUTING
   app version num: 220917
   resources: 1 CPU
   estimated CPU time remaining: 1379.480287
   elapsed task time: 5858.009798
   slot: 1
   PID: 2221366
   CPU time at last checkpoint: 5690.500000
   current CPU time: 5712.920000
   fraction done: 0.809000
   swap size: 1051 MB
   working set size: 973 MB
2) -----------
   name: wu_1664392603_228908_0
   WU name: wu_1664392603_228908
   project URL: https://boinc.loda-lang.org/loda/
   received: Thu Oct  6 15:31:53 2022
   report deadline: Thu Oct 13 15:31:53 2022
   ready to report: no
   state: downloaded
   scheduler state: scheduled
   active_task_state: EXECUTING
   app version num: 220917
   resources: 1 CPU
   estimated CPU time remaining: 1393.925106
   elapsed task time: 5849.961764
   slot: 7
   PID: 2221367
   CPU time at last checkpoint: 5654.640000
   current CPU time: 5682.160000
   fraction done: 0.807000
   swap size: 802 MB
   working set size: 728 MB
...

And here's the final output I want :

boinc.loda wu_1664392603_2288 80.9 07/10 01h37
boinc.loda wu_1664392603_2289 80.7 07/10 02h38

I managed to get the data I want ("WU name", "project URL", "estimated CPU time remaining" AND "fraction done") from one particuliar section using this code :

${execi 60 boinccmd --get_tasks | awk -F': |://|/' '\
 /URL/ && ++i==1 {u=$3}\
 /WU/ && ++j==1 {w=$2}\
 /fraction/ && ++k==1 {p=$2}\
 /estimated/ && ++l==1 {e=strftime("%d/%m %Hh%M",$2+systime())}\
 END {printf "%.10s %.18s %3.1f %s", u, w, p*100, e}\
'}

This is quite inelegant, as I must repeat this code nth times, increasing i,j,k,l values to get the whole dataset (n is related to CPU threads, my PC has 8 threads, so I repeat the code 8 times).

I'd like the script to adapt to other CPUs, where n could be anything from 1 to ...

The obvious solution is to use a while() loop, parsing the whole dataset.

But nesting a conditional loop into an awk sequence calling an external command seems too tricky for me, and Conky scripts aren't really easy to debug, as Conky may hang without any error output or log if the script's syntax is bad.

Any help will be appreciated :)


Solution

  • Assumptions:

    • the sample input shows 2 values for estimated that are ~14.5 seconds apart (1379.480287 and 1393.925106) but the expected output is showing the estimated values as being ~61 mins apart (07/10 01h37 and 07/10 02h38); for now I'm going to assume this is due to OP's repeated runs of execi returning widely varying values for the estimated lines
    • each section of execi output always contains 4 matching lines (URL, WU, fraction, estimated) and these 4 strings only occur once within a section of execi output

    I don't have execi installed on my system so to emulate OP's exceci I've cut-n-pasted OP's sample execi results into a local file named execi.dat.

    Tweaking OP's current awk script that also allows us to eliminate the need for a bash loop (that repeatedly calls execi | awk):

    cat execi.dat | awk -F': |://|/' '
    FNR==NR     { st=systime()  }
    /URL/       { found++; u=$3 }
    /WU/        { found++; w=$2 }
    /fraction/  { found++; p=$2 }
    /estimated/ { found++; e=strftime("%d/%m %Hh%M",$2+st) }
    found==4    { printf "%.10s %.18s %3.1f %s\n", u, w, p*100, e; found=0 }
    '
    

    This generates:

    boinc.loda wu_1664392603_2288 80.9 06/10 17h47
    boinc.loda wu_1664392603_2289 80.7 06/10 17h47
    

    NOTE: the last value appears to be duplicated but that's due to the sample estimated values only differing by ~14.5 seconds