如何将命令行参数传递给 gnuplot?

我想使用 gnuplot 从数据文件(比如 Foo.data)中绘制图形。目前,我在命令文件中硬编码了数据文件名,比如 脚,脚,并运行命令 gnuplot foo.plg绘制数据。但是,我希望将数据文件名作为命令参数传递,例如,运行命令 gnuplot foo.plg foo.data。如何解析 gnuplot 脚本文件中的命令行参数?谢谢。

146618 次浏览

你也可以像建议的 给你那样通过环境传递信息。 伊斯梅尔 · 阿敏的例子在这里重复:

在外壳里:

export name=plot_data_file

在 Gnuplot 的剧本中:

#! /usr/bin/gnuplot


name=system("echo $name")
set title name
plot name using ($16 * 8):20 with linespoints notitle
pause -1

您可以通过 -e开关输入变量

$ gnuplot -e "filename='foo.data'" foo.plg

然后可以在 foo.plg 中使用该变量

$ cat foo.plg
plot filename
pause -1

为了让“ foo.plg”更通用一些,可以使用一个条件语句:

if (!exists("filename")) filename='default.dat'
plot filename
pause -1

请注意,-e必须位于文件名之前,否则文件将在 -e语句之前运行。特别是,使用 ./foo.plg -e ...CLI 参数运行 shebang gnuplot #!/usr/bin/env gnuplot将忽略使用所提供的参数。

你甚至可以使用一些贝壳魔法,例如:

#!/bin/bash
inputfile="${1}" #you could even do some getopt magic here...


################################################################################
## generate a gnuplotscript, strip off bash header
gnuplotscript=$(mktemp /tmp/gnuplot_cmd_$(basename "${0}").XXXXXX.gnuplot)


firstline=$(grep -m 1 -n "^#!/usr/bin/gnuplot" "${0}")
firstline=${firstline%%:*} #remove everything after the colon
sed -e "1,${firstline}d" < "${0}" > "${gnuplotscript}"




################################################################################
## run gnuplot
/usr/bin/gnuplot -e "inputfile=\"${inputfile}\"" "${gnuplotscript}"
status=$?
if [[ ${status} -ne 0 ]] ; then
echo "ERROR: gnuplot returned with exit status $?"
fi


################################################################################
## cleanup and exit
rm -f "${gnuplotscript}"
exit ${status}


#!/usr/bin/gnuplot
plot inputfile using 1:4 with linespoints
#... or whatever you want

我的实现稍微复杂一些(例如,替换 sed 调用中的一些魔术标记,而我已经在做了... ...) ,但是为了更好地理解,我简化了这个示例。 你也可以让它变得更简单... ... YMMV。

你可以在 unix/linux 环境下使用 trick:

  1. 在 gnuplot 程序中: plot“/dev/stdin”..。

  2. 在命令行中: gnuplot program. plot < data.dat

拉马宁的回答是最好的解决方案。我想解释一下如何在 shell 变量中使用多个输入参数:

output=test1.png
data=foo.data
gnuplot -e "datafile='${data}'; outputname='${output}'" foo.plg

和 foo.plg:

set terminal png
set outputname
f(x) = sin(x)
plot datafile

正如您所看到的,更多的参数使用分号传递(如 Bash 脚本) ,但是字符串变量需要用’’(gnuplot 语法,NOT Bash 语法)封装

还有一种方法是:

您有一个 gnuplot 脚本,名为 scriptname.gp:

#!/usr/bin/gnuplot -p
# This code is in the file 'scriptname.gp'
EPATH = $0
FILENAME = $1


plot FILENAME

现在,您可以通过这种复杂的平和语法调用 gnuplot 脚本 scriptname.gp:

echo "call \"scriptname.gp\" \"'.'\" \"'data.dat'\"" | gnuplot

您可以从5.0版本开始向 gnuplot 脚本传递参数,标志为 -c。通过变量 ARG0ARG9访问这些参数,ARG0是脚本,ARG1ARG9是字符串变量。参数的数目由 ARGC给出。

例如,下面的脚本(“ script.gp”)

#!/usr/local/bin/gnuplot --persist


THIRD=ARG3
print "script name        : ", ARG0
print "first argument     : ", ARG1
print "third argument     : ", THIRD
print "number of arguments: ", ARGC

可称为:

$ gnuplot -c script.gp one two three four five
script name        : script.gp
first argument     : one
third argument     : three
number of arguments: 5

或者在 gnuplot 中

gnuplot> call 'script.gp' one two three four five
script name        : script.gp
first argument     : one
third argument     : three
number of arguments: 5

在 gnuplot 4.6.6及更早版本中,存在一种 call机制,它具有不同的(现在已经废弃的)语法。参数通过 $#$0、 ... 、 $9访问。例如,上面的脚本看起来像:

#!/usr/bin/gnuplot --persist


THIRD="$2"
print "first argument     : ", "$0"
print "second argument    : ", "$1"
print "third argument     : ", THIRD
print "number of arguments: ", "$#"

在 gnuplot 中调用它(请记住,版本 < 4.6.6)

gnuplot> call 'script4.gp' one two three four five
first argument     : one
second argument    : two
third argument     : three
number of arguments: 5

注意脚本名没有变量,因此 $0是第一个参数,变量在引号中调用。没有办法直接从命令行使用它,只能像@con-fu-se 建议的那样使用技巧。

这个问题已经得到了很好的回答,但是我认为我可以找到一个合适的位置来填补这个空缺,哪怕只是为了减少像我这样在谷歌上搜索的人的工作量。Vagoberto 的答案给了我解决这个问题所需要的东西,所以我将在这里分享我的解决方案。

我在一个最新的环境中开发了一个剧情脚本,它允许我这样做:

#!/usr/bin/gnuplot -c
set terminal png truecolor transparent crop
set output ARG1
set size 1, 0.2
rrLower = ARG2
rrUpper = ARG3
rrSD = ARG4
resultx = ARG5+0 # Type coercion required for data series
resulty = 0.02 # fixed
# etc.

在最近使用 gnuplot (在我的例子中是5.0.3)的环境中,从命令行可以很好地执行这个命令。

$ ./plotStuff.gp 'output.png' 2.3 6.7 4.3 7

当上传到我的服务器并执行时,它失败了,因为服务器版本是4.6.4(当前在 Ubuntu 14.04 LTS 上)。 下面的垫片解决了这个问题,而不需要任何改变原来的脚本。

#!/bin/bash
# GPlot v<4.6.6 doesn't support direct command line arguments.
#This script backfills the functionality transparently.
SCRIPT="plotStuff.gp"
ARG1=$1
ARG2=$2
ARG3=$3
ARG4=$4
ARG5=$5
ARG6=$6


gnuplot -e "ARG1='${ARG1}'; ARG2='${ARG2}'; ARG3='${ARG3}'; ARG4='${ARG4}'; ARG5='${ARG5}'; ARG6='${ARG6}'" $SCRIPT

这两个脚本的组合允许将参数从 bash 传递到 gnuplot 脚本,而无需考虑 gnuplot 版本,基本上可以在任何 * nix 中传递。

在 shell 中写入

gnuplot -persist -e "plot filename1.dat,filename2.dat"

以及您想要的连续文件。 只要用户不手动退出 gnuplot 屏幕,就可以使用 keep。

@ Vagoberto 的回答似乎是最好的,恕我直言,我还有一个小小的改进要补充。

Vagoberto 的建议是:

#!/usr/local/bin/gnuplot --persist


THIRD=ARG3
print "script name        : ", ARG0
print "first argument     : ", ARG1
print "third argument     : ", THIRD
print "number of arguments: ", ARGC

叫这个名字的人是:

$ gnuplot -c script.gp one two three four five
script name        : script.gp
first argument     : one
third argument     : three
number of arguments: 5

对于像我这样懒惰的打字员,可以使脚本可执行(chmod 755 script.gp)

然后使用以下方法:

#!/usr/bin/env gnuplot -c


THIRD=ARG3
print "script name        : ", ARG0
print "first argument     : ", ARG1
print "third argument     : ", THIRD
print "number of arguments: ", ARGC

并以下列方式执行:

$ ./imb.plot a b c d
script name        : ./imb.plot
first argument     : a
third argument     : c
number of arguments: 4