Як передати аргумент командного рядка gnuplot?


148

Я хочу використовувати gnuplot для малювання фігури з файлу даних, скажімо foo.data . В даний час я жорстко кодував ім'я файлу даних у командному файлі, скажімо foo.plt , і запускаю команду gnuplot foo.plgдля побудови даних. Однак я хочу передати ім'я файлу даних як аргумент команди, наприклад, запущена команда gnuplot foo.plg foo.data. Як проаналізувати аргументи командного рядка у файлі скрипту gnuplot? Дякую.

Відповіді:


191

Ви можете вводити змінні через комутатор -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операторами. Зокрема, запуск gbuplot shebang #!/usr/bin/env gnuplotз ./foo.plg -e ...аргументами CLI ігнорує використання наданих аргументів.


20
Це також можна використовувати ifдля постачання за замовчуванням. if ! exists("filename") filename='default.data'
mgilson

10
Для людей , наштовхнутися на це зараз, коментар mgilson в і Gnuplot 4.6 3 номери патчів вимагають if (!exists("filename")замість if ! exists("filename").
Сем Муссманн

Як зробити те ж саме у вікнах?
падаван

6
@Chong: або об'єднайте їх разом, або наведіть кожен -eаргумент, наприклад, -e "filename='default.data'; foo='bar'"або -e "filename='default.data'" -e "foo='bar"'.
Тор

1
Примітка. Цей -e ...параметр повинен передувати імені файлу. Дійсно, man gnuplotми можемо прочитати: -e"список команд" виконує запитувані команди перед завантаженням наступного вхідного файлу . .
Гастур

57

Ви можете передавати аргументи до сценарію gnuplot з версії 5.0 із прапором -c. Доступ до цих аргументів здійснюється через змінні ARG0до ARG9, ARG0будучи сценарієм, і ARG1до ARG9рядкових змінних. Кількість аргументів задається 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.


Я намагався використовувати -cперемикач зі сценарієм, який містить такі рядки, як plot 'data' using 0:($1/100). gnuplotвмирає з помилковим виразом помилки, оскільки $1він зник. Де я помиляюся? Зауважте, що без -cцього сценарій працює успішно.
lorcap

Я перевірив це gnuplot 5.0, додавши до цих прикладів такий рядок, як plot 'data' using 0:($1/100)і не отримав те, що ти сказав. Це буде рідко, оскільки ця версія визначає змінні ARG0- ARG9, а не $1- $9. Я припускаю, що ви також маєте версію 5.0 (чи не так?), Оскільки -cпрапор не підтримується попередніми версіями. Мені потрібно переглянути мінімальний сценарій, щоб побачити, де справжня проблема: /
vagoberto

Я бігаю gnuplot 5.0 patchlevel 0під cygwin . Однорядковий сценарій print ARG1; plot 'data' using 0:($1/100)правильно надрукує значення, передане як, ARG1а потім виходить з помилковим виразом помилки, що вказує на косу рису print ARG1; plot 'data' using 0:(/100).
lorcap

27

Ви також можете передавати інформацію через навколишнє середовище, як пропонується тут . Приклад Ісмаїла Аміна тут повторюється:

У оболонці:

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

6
Замість експорту ви можете ввести name=plot_data_file ./the_gnuplot_script.
Едгар Боне

@Edgar Bonet: Яка версія gnuplot потрібна для цього? Здається, це не працює на машині, яка використовує 4.2 ...
Бьорн

Привіт @Bjoern! Я використовую Gnuplot 4.6, але це не функція Gnuplot, це особливість оболонки: name=value commandговорить оболонці запустити команду з цією певною змінною у її середовищі. Я використовую bash 4.3.11, але я вважаю, що це дуже поширена функція оболонки.
Едгар Бонет

23

Відповідь Ярі Лааманена - найкраще рішення. Я хочу просто пояснити, як використовувати більше 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)


1
Для самого gnuplot не має значення, використовуєте ви 'або "для рядків. Зовнішні лапки навколо -eаргументу повинні бути "замінені bash змінними. Також чудово працює:OUTPUT=foobar; gnuplot -e "output=\"$OUTPUT\"; print output"
Крістоф

Дякую за підтвердження, що я можу використовувати напівколонки для розділення команд. Жодна з інших відповідей цього не свідчить.
tommy.carstensen

14

Ви можете використовувати хитрість у середовищі unix / linux:

  1. у програмі gnuplot: сюжет "/ dev / stdin" ...

  2. У командному рядку: gnuplot program.plot <data.dat


12

На це питання добре відповіли, але я думаю, що я можу знайти нішу, яку потрібно заповнити тут незалежно, якби тільки зменшити навантаження на когось, гулячи таким чином, як я. Відповідь вагоберто дав мені те, що мені потрібно, щоб вирішити свою версію цієї проблеми, і тому я поділюсь тут своїм рішенням.

Я розробив сценарій сюжету в сучасному середовищі, що дозволило мені:

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


5

Ви навіть можете зробити якусь магію оболонки, наприклад, наприклад:

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

Моя реалізація дещо складніша (наприклад, заміна деяких магічних маркерів у сед-дзвінку, поки я вже на цьому ...), але я спростила цей приклад для кращого розуміння. Ви також можете зробити це ще простіше .... YMMV.


4

У оболонці напишіть

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

і послідовно потрібні файли. -persist використовується для того, щоб екран gnuplot залишався до тих пір, поки користувач не вийде з нього вручну.


На консолі Win7 варіант -персист, здається, не працює? Наприклад, gnuplot -persist -c "myscript.plt" "mydata.csv" "myoutput.png"ця команда працює в порядку, і я отримую файл "myoutput.png", як я очікував, але екран gnuplot не з'являється ( exitкоманда НЕ в myscript.plt). Чому? І як зробити так, щоб на моєму прикладі відображалися екрани gnuplot?
lil

1

Ще один спосіб такий:

У вас є сценарій 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 

0

@ відповідь vagoberto здається найкращим IMHO, якщо вам потрібні позиційні аргументи , і я маю додати невелике вдосконалення.

пропозиція вагоберто:

#!/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
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.