【问题标题】:How to pass command line argument to gnuplot?如何将命令行参数传递给gnuplot?
【发布时间】:2012-09-01 22:58:03
【问题描述】:

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

【问题讨论】:

    标签: command-line gnuplot


    【解决方案1】:

    您还可以按照here 的建议通过环境传递信息。 Ismail Amin 的例子在这里重复:

    在外壳中:

    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
    

    【讨论】:

    • 您可以键入name=plot_data_file ./the_gnuplot_script,而不是导出。
    • @Edgar Bonet:这需要哪个 gnuplot 版本?在使用 4.2 的机器上似乎无法解决...
    • 嗨@Bjoern!我正在使用 Gnuplot 4.6,但这不是 Gnuplot 功能,它是 shell 的一个功能:name=value command 告诉 shell 在其环境中使用该特定变量运行命令。我使用的是 bash 4.3.11,但我相信这是一个非常常见的 shell 功能。
    【解决方案2】:

    您可以通过开关-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 将忽略使用提供的参数。

    【讨论】:

    • 这也可以与if 一起使用以提供默认值。 if ! exists("filename") filename='default.data'
    • 对于现在遇到这个问题的人,mgilson 的评论和 Gnuplot 4.6 补丁级别 3 需要 if (!exists("filename") 而不是 if ! exists("filename")
    • 如何在windows中做同样的事情?
    • @Chong:要么将它们串在一起,要么在-e 参数中给出每个参数,例如-e "filename='default.data'; foo='bar'"-e "filename='default.data'" -e "foo='bar"'.
    • 注意:-e ... 选项必须位于文件名之前。事实上,从man gnuplot 我们可以读到:-e“command list”在加载下一个输入文件之前执行请求的命令。.
    【解决方案3】:

    你甚至可以做一些 shell 魔法,例如像这样:

    #!/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。

    【讨论】:

      【解决方案4】:

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

      1. 在 gnuplot 程序中:绘制“/dev/stdin”...

      2. 在命令行中:gnuplot program.plot

      【讨论】:

        【解决方案5】:

        Jari Laamanen 的回答是最好的解决方案。我只想解释如何在 shell 变量中使用超过 1 个输入参数:

        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 语法,而不是 Bash 语法)

        【讨论】:

        • 对于 gnuplot 本身,使用 '" 作为字符串并不重要。 -e 参数周围的外部引号必须是 " 才能替换 bash 变量。以下也可以正常工作:OUTPUT=foobar; gnuplot -e "output=\"$OUTPUT\"; print output"
        • 感谢您确认我可以使用分号来分割命令。其他答案都没有显示这一点。
        【解决方案6】:

        还有一种方式是这样的:

        你有一个名为scriptname.gp的gnuplot脚本:

        #!/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 
        

        【讨论】:

          【解决方案7】:

          从 5.0 版开始,您可以将参数传递给带有标志 -c 的 gnuplot 脚本。这些参数通过变量ARG0ARG9ARG0 是脚本以及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 中被称为(记住,版本

          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 建议的技巧。

          【讨论】:

          • 我尝试将-c 开关与包含plot 'data' using 0:($1/100) 等行的脚本一起使用。 gnuplot 因错误 invalid expression 而死,因为 $1 消失了。我哪里错了?请注意,没有-c,脚本会成功运行。
          • 我用gnuplot 5.0 对其进行了测试,在这些示例中添加了plot 'data' using 0:($1/100) 之类的行,但没有得到你所说的。这很少见,因为这个版本定义了变量ARG0--ARG9,而不是$1--$9。我假设您也有 5.0 版(是吗?),因为早期版本不支持 -c 标志。我需要看一个最小的脚本来看看真正的问题在哪里:/
          • 我在cygwin 下运行gnuplot 5.0 patchlevel 0。单行脚本print ARG1; plot 'data' using 0:($1/100) 正确打印作为ARG1 传递的值,然后退出,错误invalid expression 指向print ARG1; plot 'data' using 0:(/100) 的斜线。
          【解决方案8】:

          这个问题得到了很好的回答,但我想我可以在这里找到一个合适的位置来填补,如果只是为了减少像我一样在谷歌上搜索的人的工作量。 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。

          【讨论】:

            【解决方案9】:

            在shell中写

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

            并连续获得您想要的文件。 -persist 用于使 gnuplot 屏幕保持不变,只要用户不手动退出它。

            【讨论】:

            • 在 Win7 控制台中,-persist 选项似乎不起作用?例如gnuplot -persist -c "myscript.plt" "mydata.csv" "myoutput.png",这个命令可以正常工作,我得到了文件“myoutput.png”,但没有出现gnuplot屏幕(myscript.plt中没有exit命令)。为什么?以及如何在我的示例中显示 gnuplot 屏幕?
            【解决方案10】:

            @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
            

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 2013-10-11
              • 1970-01-01
              • 2020-08-02
              • 2014-01-13
              • 2020-09-02
              • 2014-05-03
              • 2011-10-14
              相关资源
              最近更新 更多