【问题标题】:setting variables with gnuplot's for cycle使用 gnuplot 的 for 循环设置变量
【发布时间】:2012-06-21 13:00:46
【问题描述】:

我正在尝试使用 set for cycle 命令为 gnuplot 环境设置变量。 我使用的是 4.6 版本,根据gnuplot documention (page 70),语法如下:

for [intvar = start:end{:increment}]
for [stringvar in "A B C D"]
Examples:
set for [i = 1:10] style line i lc rgb "blue"

但我得到这个错误:

gnuplot> set for [var in gpvars] replace(var,'#_#',' ')
                                 ^
         line 0: Unrecognized option.  See 'help set'.

我的脚本:

#!/bin/bash

OUTDIRNAME="out"
TIMEFORMAT='%d.%m.%y'
GPPARS=( "xlabel "Time"" "ylabel "value1"" "y2label "value2"" "format x "%H:%M"")
GPPARS_MOD=()

for (( i=0; i < ${#GPPARS[@]}; i++)); do 
  FILE=${GPPARS[${i}]}
  echo "arg=${FILE}"
  GPPARS_MOD+=( "`echo "${FILE}" | sed -e 's/ /#_#/g'`" )
done

gnuplot << EOF
reset

replace(S,C,R)=(strstrt(S,C)) ? \
    replace( S[:strstrt(S,C)-1].R.S[strstrt(S,C)+strlen(C):] ,C,R) : S

set terminal png
set output "${OUTDIRNAME}/graph.png"
set timefmt "${TIMEFORMAT}"
set xdata time

gpvars="${GPPARS_MOD[@]}"

set for [var in gpvars] {
   replace(var,'#_#',' ')
}

...

EOF

...

exit 0 

我也在使用函数替换,因为空格(gnuplot 忽略转义序列)该函数可以完美地用于循环绘图。 我尝试过使用和不使用函数以及使用不带空格的变量,但结果是一样的。

【问题讨论】:

  • 我有点困惑你想在这里设置什么......在一个设置命令中你需要设置一些东西(例如set labelset arrow)。您正在尝试的类似于stringvar="foo"; set stringvar,这也是一个语法错误。
  • @mgilson stringvar 的值来自数组 GPARS_MOD。所以在第一次迭代的正文中应该是这样的:set xlabel "Time"
  • 我明白了。我现在正在写一个答案。

标签: bash variables for-loop gnuplot


【解决方案1】:

作为旁注——我不确定我是否相信您的 bash 数组会按照您希望的方式对事物进行分组……对我来说,您的报价被剥夺了。试试:

GPPARS=( "xlabel 'Time'" "ylabel 'value1'" "y2label 'value2'" "format x '%H:%M'")

相反。 (内部双引号替换为单引号)

这是一个棘手的问题——你使用 gnuplot 4.6 是一件好事,否则我不知道如何解决它。 (编辑 -- 使用 gnuplot 4.4,您可以使用 wordwordsifrereadexists 和宏的组合,但这是一个相当混乱的解决方案)

请注意,您所拥有的东西不起作用,因为它类似于:

MYLABEL='xlabel "foo"'
set MYLABEL

Gnuplot 在执行 set 命令之前不会扩展 MYLABEL,因此您可以执行以下操作:

MYLABEL="totally cool X label here!"
set xlabel MYLABEL

您想要的可以使用宏来完成(但可惜,不是通过迭代):

set macro 
MYLABEL='xlabel "foo"'
set @MYLABEL

但这在这里也不太适用,因为宏扩展发生在其他任何事情之前(例如函数评估)。这里需要的是 gnuplot 在 4.6 中引入的更通用的迭代结合eval

do for [ var in gpvars ] {
    eval( 'set '.replace(var,'#_#',' ') )
}

编辑——gnuplot 4.2+ 解决方案

#top of script -- Nothing should go here.
replace(S,C,R)=(strstrt(S,C)) ? \
     replace( S[:strstrt(S,C)-1].R.S[strstrt(S,C)+strlen(C):] ,C,R) : S
if( ! exists("N") ) N=1
TODO="${GPPARS_MOD[@]}"
set macro
do_set=replace(word(TODO,N),'#_#',' ')
set @do_set
N=N+1
if( N <= words(TODO) ) reread
#rest of script here ...

【讨论】:

  • 谢谢!我会在几个小时内给你反馈
  • 不幸的是,我在两个解决方案中都遇到了错误。首先(对于 4.6)我得到line 0: undefined variable: Time 第二个我得到:line 0: undefined variable: Time gnuplot&gt; N=N+1 ^ line 0: ';' expected
  • @Rob -- gnuplot 4.6 版本立即为我工作。您是否像我建议的那样更改了定义 GPVARS 数组(在 bash 中)的方式? gnuplot 4.2+ 版本有一个错误,我没有使用正确数量的参数调用replace。我已经修复并更新了。
  • 是的,这个GPPARS=( "xlabel Time" "ylabel val" ) 但我认为我在gnuplot gpvars="${GPPARS_MOD[@]}" 中犯了错误。到 4.2v 我注意到了,所以错误也仍然存在。
  • 哈,单引号也行。我还是不明白为什么。但这将是一个问题,因为数组 GPARS 中的这些值是变量 :(
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-05-05
  • 1970-01-01
  • 1970-01-01
  • 2020-12-20
  • 2019-07-05
相关资源
最近更新 更多