web-dev-qa-db-ja.com

gnuplot関数内でawkまたは他のシェルコマンドを使用する

私はこのようなものが欲しい:

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

動作していないのは、gnuplot関数内にawkがある部分です。 awkの直後にplotスクリプトを使用すると、正常に機能します。

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

awkまたは他のシェルコマンドをgnuplot関数内に配置する方法はありますか? awkスクリプトを別のファイルにアウトソーシングし、このファイルをplotの直後にawkできることは知っていますが、個別のファイルは必要ありません。

16
Juve

$varは、シェルの場合のようにgnuplot内の文字列でvarを展開しません。 gnuplotの文字列連結(.演算子を使用)を使用したい:

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

または、より快適な場合はsprintfを使用できると思います。

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

*これは実際にはコマンドを実行しないことに注意してください。 plotに渡される文字列を作成するだけで、plotがコマンドを実行します。関数内で実際にコマンドを実行したい場合は、関数としてsystemを呼び出すことができます。ドキュメントから:

`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)))
23
mgilson