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

Яри ​​Лааманен
источник
20
Это также может быть использовано ifдля предоставления значений по умолчанию. if ! exists("filename") filename='default.data'
Мгилсон
10
Для тех, кто сейчас сталкивается с этим, комментарии mgilson и Gnuplot 4.6 patchlevel 3 требуют if (!exists("filename")вместо if ! exists("filename").
Сэм Муссманн
Как сделать то же самое в Windows?
падаван
6
@ Чонг: Либо связывайте их вместе, либо приводите каждый в качестве -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.

vagoberto
источник
Я попытался использовать -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.
Эдгар Бонет
@ Эдгар Бонет: Какая версия gnuplot необходима для этого? Похоже, это не работает на машине, которая использует 4.2 ...
Bjoern
Привет, @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)

Mo3bius
источник
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

На этот вопрос хорошо ответили, но я думаю, что я могу найти здесь нишу, чтобы заполнить ее независимо, хотя бы для того, чтобы уменьшить нагрузку на кого-то, кто гуглит это, как я. Ответ от 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.

пар.
источник
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

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

Стефан
источник
4

В оболочке пиши

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

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

Анируддха Бера
источник
В консоли Win7 опция -persist не работает? Например, gnuplot -persist -c "myscript.plt" "mydata.csv" "myoutput.png"эта команда работает нормально, и я получаю файл «myoutput.png», как и ожидалось, но экран gnuplot не появляется ( exitкоманда NO в myscript.plt). Зачем? А как сделать, чтобы экран gnuplot показывал в моем примере?
ил
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 кажется лучшим ИМХО, если вам нужны позиционные аргументы , и я хочу добавить небольшое улучшение.

предложение Вагоберто:

#!/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
Бретт Холман
источник