Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

using awk or other shell command inside gnuplot function

Tags:

awk

gnuplot

I want something like this:

file1='logs/last/mydata1.log'
file2='logs/last/mydata2.log'

# declare function that uses awk to reshape the data - does not work :(
sum1(fname)=("<awk '{sum=0; for(i=8;i<=NF;i+=2) sum+=$i; print $1,sum/2}' $fname")
sum2(fname)=("<awk '{sum=0; for(i=9;i<=NF;i+=2) sum+=$i; print $1,sum/2}' $fname")

# plot different columns of my file and awk processed file
plot file1 u 1:2 title "thing A measure 1" w l, \
     file1 u 3:4 title "thing A measure 2" w l, \
     file2 u 1:2 title "thing B measure 1" w l, \
     file2 u 3:4 title "thing B measure 2" w l, \
     sum1(file1) u 1:2 title "group A measure 1" w l, \
     sum2(file1) u 1:2 title "group A measure 2" w l, \
     sum1(file2) u 1:2 title "group B measure 1" w l, \
     sum2(file2) u 1:2 title "group B measure 2" w l

What is not working is the part with awk inside a gnuplot function. Using my awk script directly after plot works fine:

plot "<awk '{sum=0; for(i=9;i<=NF;i+=2) sum+=$i; print $1,sum}' ./logs/last/mydata1.log" u 1:2 w l

Is there a way to put awk or other shell commands inside a gnuplot function? I know I could outsource the awk script to another file and awk this file directly after plot, but I don't want separate files.

like image 533
Juve Avatar asked Oct 11 '12 19:10

Juve


1 Answers

$var doesn't expand var in a string within gnuplot like it would in a shell. You want to use gnuplot's string concatenation (which uses the . operator):

sum1(fname)="<awk '{sum=0; for(i=8;i<=NF;i+=2) sum+=$i; print $1,sum/2}' ".fname

Or, I suppose you could use sprintf if you find that more comfortable:

sum1(fname)=sprintf("<awk '{sum=0; for(i=8;i<=NF;i+=2) sum+=$i; print $1,sum/2}' %s",fname)

*Note that this doesn't actually execute the command. It just builds the string which will be passed to plot and then plot will execute the command. If you actually want to execute a command in a function, you can call system as a function. From the docs:

`system "command"` executes "command" using the standard shell. See `shell`.
 If called as a function, `system("command")` returns the resulting character
 stream from stdout as a string.  One optional trailing newline is ignored.

 This can be used to import external functions into gnuplot scripts:

       f(x) = real(system(sprintf("somecommand %f", x)))
like image 76
mgilson Avatar answered Nov 02 '22 12:11

mgilson