替换和命令行宏
当 gnuplot 命令被第一次读取时,即,在它被解释或执行之前,执行两种形式的词法替换。这些触发条件是文本由反引号 (ascii 字符 96) 括住或者以@
(ascii 字符 64) 开头。
反引号内系统命令替换
命令行替换由反引号中的系统命令指定。反引号中的系统命令被执行并且其输出用来替换反引号中的文本。该系统命令的退出状态返回到变量 GPVAL_SYSTEM_ERRNO 和 GPVAL_SYSTEM_ERRMSG。参考system。
命令行替换可以用在gnuplot命令行的任何地方,除了单引号括住的字符串内。
示例
运行程序leastsq并将其输出替换命令行中的leastsq(包括反引号):
f(x) = `leastsq`
或者,在 VMS
f(x) = `run leastsq`
用当前时间和用户 ID 生成标签:
set label "generated on `date +%Y-%m-%d` by `whoami`" at 1,1
set timestamp "generated on %Y-%m-%d by `whoami`"
作为宏的字符串变量替换
字符@
用于触发将字符串变量的当前值替换到命令行中。字符串的文本可以包含任意数量的词法元素。这允许字符串变量用作命令行宏。只有字符串常量可以用这种机制扩展,字符串求值表达式不行。例如:
style1 = "lines lt 4 lw 2"
style2 = "points lt 3 pt 5 ps 2"
range1 = "using 1:3"
range2 = "using 1:5"
plot "foo" @range1 with @style1, "bar" @range2 with @style2
包含@
符号的行在输入时展开,所以在执行时,效果与完全输入一样
plot "foo" using 1:3 with lines lt 4 lw 2, \
"bar" using 1:5 with points lt 3 pt 5 ps 2
函数exists()
与宏评估结合使用可能有用。下面的例子检查是否 C 可以安全地展开为用户定义变量的名称:
C = "pi"
if (exists(C)) print C," = ", @C
宏展开不会发生在单引号或双引号内。然而宏展开确实可以出现在反引号中。
宏展开是解释器在处理一条新的命令行时,要做的第一件事,而且只做一次。因此,像下面的代码可以正确执行:
A = "c=1"
@A
但下面一行就不能正确执行,因为宏定义在同一行,不能及时展开
A = "c=1"; @A # 不会展开为 c=1
为了执行完整的命令,evaluate命令可能也很便利。
字符串变量、宏和命令行替换
字符串变量、反引号和宏替换的交互某种程度来说有点复杂。反引号不会阻止宏替换,因此
filename = "mydata.inp"
lines = ` wc --lines @filename | sed "s/ .*//" `
结果是 mydata.inp 文件的行数被保存在整数变量 lines 中。而双引号不会阻止反引号替换,因此
mycomputer = "`uname -n`"
结果是系统命令uname -n
返回的字符串保存在字符串变量 mycomputer 中。
但是,双引号内不执行宏替换,所以将一个系统命令定义为一个宏,然后同时使用宏和反引号替换。
machine_id = "uname -n"
mycomputer = "`@machine_id`" # 不奏效!!
这会失败,因为双引号阻止@machine_id
被解释为宏。要将系统命令保存为宏并稍后执行,必须将反引号包括为宏本身的一部分。这可以通过如下所示的宏定义实现。注意, sprintf 格式嵌套了所有 3 种类型的引号。
machine_id = sprintf('"`uname -n`"')
mycomputer = @machine_id