Как сохранить вывод команды gnuplot в (строковую) переменную? Например, мне нужно знать текущую настройку формата xdata в «вызываемом» вспомогательном сценарии, но я не могу вспомнить, как ее сохранить. например
gnuplot> show xdata
x is set to time
Но как мне сохранить или получить доступ к этому состоянию?
Я не вижу никакой переменной GP_VAL
, которая делала бы это состояние доступным, и я уверен, что есть и другие состояния, к которым трудно получить доступ в скрипте.
Большое спасибо :-)
Это тот случай, когда небольшой вспомогательный сценарий многократного использования должен знать, что установил вызывающий объект.
Раньше мне также хотелось, чтобы некоторые параметры, которые можно отображать с помощью show ...
, можно было поместить в переменную. Я не знаю, можно ли это легко сделать с помощью gnuplot сейчас, но, может быть, в будущем?
Насколько я понимаю, ваш вопрос вы хотите узнать в сценарии, установлено ли xdata
на time
или нет. Если вы отметите help xdata
, настройка может быть time
или numeric
.
Один из возможных обходных путей, чтобы выяснить это:
save
(отметьте help save
), очевидно, вы не можете сохранить его в блоке данных.xdata
значение timedata. Если установлено время, то строка для поиска — это set xdata time
, а если она установлена на числовую, строка — это только set xdata
, что немного усложняет извлечение (возможно, есть более простой способ).
Файл будет выглядеть так:#
# G N U P L O T
# Version 6.0 patchlevel 0 last modified 2023-12-09
#
# Copyright (C) 1986-1993, 1998, 2004, 2007-2023
# Thomas Williams, Colin Kelley and many others
#
# gnuplot home: http://www.gnuplot.info
# faq, bugs, etc: type "help FAQ"
# immediate help: type "help" (plot window: hit 'h')
# set terminal qt 0 font "Sans,10"
# set output
unset clip points
set clip one
unset clip two
unset clip radial
set errorbars front 1.000000
set border 31 front lt black linewidth 1.000 dashtype solid
set cornerpoles
set zdata
set ydata
set xdata time
set y2data
set x2data
set boxwidth
set boxdepth 0
set style fill empty border
...
К сожалению, gnuplot не предназначен для парсинга, но вы, тем не менее, можете это сделать.
Скрипт: (требуется gnuplot>=6.0 из-за функционального блока)
### return setting for xdata
reset session
function $xdata(none) <<EOF
FILE = "Settings.txt"
save FILE
set table $Dummy
plot FILE u 0:(strcol(2) eq "xdata" ? \
XDATA=(strlen(' '.strcol(3))>3 ? "time" : "numeric") : 0) w table
unset table
return XDATA
EOF
set xdata
print $xdata(0)
set xdata time
print $xdata(0)
### end of script
Результат:
numeric
time
Скрипт: (требуется gnuplot>=5.0.0 из-за блоков данных)
### return setting for xdata
reset session
set xdata
FILE = "SO78723633.txt"
save FILE
set table $Dummy
plot FILE u 0:(strcol(2) eq "xdata" ? \
XDATA=(strlen(' '.strcol(3))>3 ? "time" : "numeric") : 0) w table
unset table
print XDATA
set xdata time
FILE = "SO78723633.txt"
save FILE
set table $Dummy
plot FILE u 0:(strcol(2) eq "xdata" ? \
XDATA=(strlen(' '.strcol(3))>3 ? "time" : "numeric") : 0) w table
unset table
print XDATA
### end of script
Результат:
numeric
time
Добавление:
Как упоминалось в комментариях, вышеуказанные решения зависят от настройки разделителя файлов данных. Если это было установлено, например. set datafile separator comma
эти решения не сработают.
Следовательно, вот решение, которое использует системно-зависимый вызов, однако оно работает под Windows без предварительной установки некоторых утилит, таких как grep
, gawk
, coreutils
и т. д. Сохраненный файл сценария считывается 1:1 в блок данных., а затем проверил через strstrt()
(отметьте help strstrt
).
Скрипт: (требуется gnuplot>=5.2.0 из-за индексации блоков данных)
set xdata time # e.g. set in the caller script
TEMP = "Temp.txt"
save TEMP
FileToDatablock(f,d) = GPVAL_SYSNAME[1:7] eq "Windows" ? \
sprintf('< echo %s ^<^<EOD & type "%s"',d,f) : \
sprintf('< echo "\%s <<EOD" & cat "%s"',d,f) # Linux/MacOS
load FileToDatablock(TEMP,'$Settings')
do for [i=1:|$Settings|] {
if (strstrt($Settings[i],'set xdata')==1) { XDATA = $Settings[i] }
}
print XDATA
Результат:
set xdata time
Отлично, я подумал, что, возможно, был какой-то «трюк» с чем-то вроде gprintf или чего-то подобного, который я не мог вспомнить. Благодарим вас за добавление решения версии 5.0. В качестве альтернативы можно fgrep
(или что-то еще) файл, если это терпимо. Решение работает в небольшом вспомогательном сценарии, который «вызывается», что было моим требованием - сценарий многократного использования не знает, что установил вызывающий объект.
@mjp ок, понятно. Если возможно, я предпочитаю решения только для gnuplot, которые не зависят от платформы. Однако предостережение для этого решения заключается в том, что ваш сценарий «вызывающий абонент» мог выполнить set datafile separator comma
, тогда strcol(3)
не будет работать. Затем вы можете временно установить его на whitespace
и вернуть все, что было раньше. Однако, чтобы это узнать, нужно сделать show datafile
. Ааа...! Итак, тогда в конечном итоге может потребоваться системно-зависимая grep
или что-то в этом роде. Возможно, есть еще способ, предназначенный только для gnuplot.
Ах, да, еще одно из упомянутых мною «состояний» отсутствует. Я не уверен, какое исправление gnuplot является лучшим. Прошло несколько лет с тех пор, как я в последний раз представлял исправления ошибок, и мне не очень хочется снова погружаться в банкомат. Добавление дополнительных переменных GPVAL_
ограничено, так как всегда могут возникнуть другие ситуации или что-то может быть пропущено. Возможно, лучше всего создать gprintf()
«%C» или позволить evaluate
возвращать текст команды, как это может сделать команда system("cmd")
. Возможно, нам стоит посмотреть, как кодируется evaluate
, и сравнить с system()
Простой ответ, если вы не против создать временный файл с помощью стандартных команд оболочки *nix.
gnuplot> set xdata time
gnuplot> tempfile = system("mktemp")
gnuplot> save tempfile
gnuplot> query = "grep 'set xdata' " . tempfile
gnuplot> response = system(query)
gnuplot> print response
set xdata time
Спасибо, хорошее и простое решение, поскольку у меня старый Mac (а macports в настоящее время не работает с gnuplot примерно в версии 5.0). Единственная проблема заключается в том, что я вижу, что нет способа проверить, произошел ли сбой системного вызова. GPVAL_ERRNO
кажется, не установлен, когда я проверяю это. Возможно, это ошибка, которую исправили.
Gnuplot делает простую вещь и выполняет команды системной оболочки через popen(). Но popen() возвращает ошибку только в том случае, если создание канала не удалось, а не в случае сбоя на другом конце успешно открытого канала.
Что именно вы хотите сделать, если у вас есть формат? Обычно вы сами устанавливаете формат в своем скрипте, поэтому вам следует знать, что это такое. Я могу только представить, что вы хотите что-то автоматизировать или какие-то внешние скрипты задают формат. Не могли бы вы объяснить подробнее, что вы хотите сделать?