2

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 :)

  • please update the question to show the expected output (corresponding to the sample input); also for clarification ... what part of your `awk` code are you referring to as *`calling an external command`*? – markp-fuso Oct 06 '22 at 20:43
  • Hi mark-fuso ! The external command is called as is : `execi 60 boinccmd --get_tasks`, meaning "execute every 60 seconds the command boinccmd --get_tasks". The output is tunneled to awk using the "|" character. I've updated the initial post to show what I want to get as a final output. – Guillaume J. Oct 06 '22 at 21:47
  • ah, ok, I misunderstood your comment; you were talking about calling `execi` for each pass through a `bash` loop; while a single `awk` call will likely have the best performance ... from a `bash` loop perspective you could run `execi` and redirect the output to a file and then inside your `bash` loop have your `awk` script read the file (not as efficient as a single `awk` call but would eliminate the multiple `execi` calls) – markp-fuso Oct 06 '22 at 21:50
  • Yep :) I'd like to avoid any call to an external bash or lua script, but this would be better than my actual "manual loop". The real point is I'd like the script to detect the number of sections and extract, transform and print values accordingly. – Guillaume J. Oct 06 '22 at 21:56

1 Answers1

2

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

markp-fuso
  • 28,790
  • 4
  • 16
  • 36
  • 1
    Many thanks ! I had to adapt the syntax, as Conky is a bit ticklish with new lines and spaces (no fancy indented code allowed), but it works great otherwise ! Also : the `estimated` data discrepancy doesn't exist : as I couldn't copy/paste output (it goes in a background display layer, see Conky for details), I must have made a typo while retyping it here. Thanks again ! – Guillaume J. Oct 07 '22 at 10:31