Wie übergebe ich ein Befehlszeilenargument an gnuplot?

148

Ich möchte gnuplot verwenden, um Zahlen aus einer Datendatei zu zeichnen, sagen wir foo.data . Derzeit habe ich den Datendateinamen in der Befehlsdatei fest codiert , z. B. foo.plt , und den Befehl ausgeführt gnuplot foo.plg, um Daten zu zeichnen. Ich möchte jedoch den Datendateinamen als Befehlsargument übergeben, z gnuplot foo.plg foo.data. B. Befehl ausführen . Wie analysiere ich die Befehlszeilenargumente in der Gnuplot-Skriptdatei? Vielen Dank.

Yun Huang
quelle

Antworten:

191

Sie können Variablen per Schalter eingeben -e

$ gnuplot -e "filename='foo.data'" foo.plg

In foo.plg können Sie diese Variable dann verwenden

$ cat foo.plg 
plot filename
pause -1

Verwenden Sie eine Bedingung, um "foo.plg" etwas allgemeiner zu gestalten:

if (!exists("filename")) filename='default.dat'
plot filename
pause -1

Beachten Sie, dass dies -evor dem Dateinamen stehen muss, da die Datei sonst vor den -eAnweisungen ausgeführt wird. Insbesondere beim Ausführen eines Shebang-Gnuplots #!/usr/bin/env gnuplotmit ./foo.plg -e ...CLI-Argumenten werden die angegebenen Argumente ignoriert.

Jari Laamanen
quelle
20
Dies kann auch verwendet werden if, um Standardeinstellungen bereitzustellen. if ! exists("filename") filename='default.data'
mgilson
10
Für Leute, die jetzt darüber stolpern, erfordern mgilsons Kommentar und Gnuplot 4.6 Patchlevel 3 if (!exists("filename")anstelle von if ! exists("filename").
Sam Mussmann
Wie mache ich dasselbe in Windows?
Padawan
6
@Chong: Entweder sie aneinander reihen oder jedes in einem -eArgument angeben , zB -e "filename='default.data'; foo='bar'"oder -e "filename='default.data'" -e "foo='bar"'.
Thor
1
Hinweis: Die -e ...Option muss vor dem Dateinamen stehen. In der Tat man gnuplotkönnen wir lesen: -e"Befehlsliste" führt die angeforderten Befehle aus, bevor die nächste Eingabedatei geladen wird . .
Hastur
57

Sie können Argumente mit dem Flag an ein Gnuplot-Skript seit Version 5.0 übergeben -c. Diese Argumente werden durch die Variablen zugegriffen ARG0zu ARG9, ARG0das Skript zu sein, und ARG1auf ARG9String - Variablen. Die Anzahl der Argumente ist gegeben durch ARGC.

Zum Beispiel das folgende Skript ("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 

kann genannt werden als:

$ gnuplot -c script.gp one two three four five
script name        : script.gp
first argument     : one
third argument     : three
number of arguments: 5

oder innerhalb von gnuplot als

gnuplot> call 'script.gp' one two three four five
script name        : script.gp
first argument     : one
third argument     : three
number of arguments: 5

In Gnuplot 4.6.6 und früheren Versionen gibt es einen callMechanismus mit einer anderen (jetzt veralteten) Syntax. Die Argumente werden zugegriffen durch $#, $0, ..., $9. Das obige Skript sieht beispielsweise folgendermaßen aus:

#!/usr/bin/gnuplot --persist

THIRD="$2"
print "first argument     : ", "$0"
print "second argument    : ", "$1"
print "third argument     : ", THIRD
print "number of arguments: ", "$#"

und es wird in gnuplot als (denken Sie daran, Version <4.6.6) aufgerufen.

gnuplot> call 'script4.gp' one two three four five
first argument     : one
second argument    : two
third argument     : three
number of arguments: 5

Beachten Sie, dass es keine Variable für den Skriptnamen gibt, ebenso $0wie das erste Argument, und die Variablen in Anführungszeichen aufgerufen werden. Es gibt keine Möglichkeit, dies direkt über die Befehlszeile zu verwenden, nur durch Tricks, wie sie von @ con-fu-se vorgeschlagen wurden.

vagoberto
quelle
Ich habe versucht, den -cSchalter mit einem Skript zu verwenden, das Zeilen wie enthält plot 'data' using 0:($1/100). gnuplotstirbt mit dem Fehler ungültiger Ausdruck, weil $1verschwunden ist. Wo irre ich mich Beachten Sie, dass -cdas Skript ohne erfolgreich ausgeführt wird.
Lorcap
Ich habe es getestet, gnuplot 5.0indem ich diesen Beispielen eine Zeile wie hinzugefügt habe plot 'data' using 0:($1/100), und habe nicht verstanden, was Sie sagen. Es wäre selten, da diese Version die Variablen definiert ARG0- ARG9und nicht $1- $9. Ich gehe davon aus, dass Sie auch Version 5.0 haben (oder?), Da das -cFlag von früheren Versionen nicht unterstützt wird. Ich würde ein minimales Skript sehen müssen, um zu sehen, wo das eigentliche Problem liegt: /
vagoberto
Ich laufegnuplot 5.0 patchlevel 0 unter Cygwin . Das einzeilige Skript print ARG1; plot 'data' using 0:($1/100)druckt den als übergeben übergebenen Wert korrekt ARG1und wird dann mit dem Fehler ungültiger Ausdruck beendet , der auf den Schrägstrich von zeigt print ARG1; plot 'data' using 0:(/100).
Lorcap
27

Sie können Informationen auch wie empfohlen über die Umgebung weitergeben hier . Das Beispiel von Ismail Amin wird hier wiederholt:

In der Shell:

export name=plot_data_file

In einem Gnuplot-Skript:

#! /usr/bin/gnuplot

name=system("echo $name")
set title name
plot name using ($16 * 8):20 with linespoints notitle
pause -1
Thor
quelle
6
Anstelle des Exports können Sie eingeben name=plot_data_file ./the_gnuplot_script.
Edgar Bonet
@ Edgar Bonet: Welche Gnuplot-Version wird dafür benötigt? Es scheint nicht auf Ihrer Maschine zu funktionieren, die 4.2 ...
Bjoern
Hallo @Bjoern! Ich verwende Gnuplot 4.6, aber dies ist keine Gnuplot-Funktion, sondern eine Funktion der Shell: name=value commandWeist die Shell an, den Befehl mit dieser bestimmten Variablen in ihrer Umgebung auszuführen. Ich verwende Bash 4.3.11, aber ich glaube, es ist eine sehr häufige Shell-Funktion.
Edgar Bonet
23

Die Antwort von Jari Laamanen ist die beste Lösung. Ich möchte nur erklären, wie mehr als 1 Eingabeparameter mit Shell-Variablen verwendet werden:

output=test1.png
data=foo.data
gnuplot -e "datafile='${data}'; outputname='${output}'" foo.plg

und foo.plg:

set terminal png
set outputname 
f(x) = sin(x)
plot datafile

Wie Sie sehen können, werden mehr Parameter mit Semikolons übergeben (wie in Bash-Skripten), aber Zeichenfolgenvariablen MÜSSEN mit '' gekapselt werden (Gnuplot-Syntax, NICHT Bash-Syntax).

Mo3bius
quelle
1
Für Gnuplot selbst spielt es keine Rolle, ob Sie 'oder "für Zeichenfolgen verwenden. Die äußeren Anführungszeichen um das -eArgument müssen darin bestehen ", dass die Bash-Variablen ersetzt werden. Das Folgende funktioniert auch gut:OUTPUT=foobar; gnuplot -e "output=\"$OUTPUT\"; print output"
Christoph
Vielen Dank für die Bestätigung, dass ich Semikolons zum Teilen von Befehlen verwenden kann. Keine der anderen Antworten zeigt dies.
Tommy.carstensen
14

Sie können Trick in Unix / Linux-Umgebung verwenden:

  1. im Gnuplot-Programm: plot "/ dev / stdin" ...

  2. In der Befehlszeile: gnuplot program.plot <data.dat

arto
quelle
12

Diese Frage ist gut beantwortet, aber ich denke, ich kann hier eine Nische finden, die ich trotzdem füllen kann, wenn auch nur, um die Arbeitsbelastung für jemanden zu verringern, der so googelt wie ich. Die Antwort von vagoberto gab mir das, was ich brauchte, um meine Version dieses Problems zu lösen, und deshalb werde ich meine Lösung hier teilen.

Ich habe ein Plot-Skript in einer aktuellen Umgebung entwickelt, mit dem ich Folgendes tun konnte:

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

Dies funktioniert perfekt über die Befehlszeile in einer Umgebung mit einem aktuellen Gnuplot (in meinem Fall 5.0.3).

$ ./plotStuff.gp 'output.png' 2.3 6.7 4.3 7

Beim Hochladen auf meinen Server und Ausführen schlug dies fehl, da die Serverversion 4.6.4 war (aktuell unter Ubuntu 14.04 LTS). Das folgende Shim löste dieses Problem, ohne dass Änderungen am ursprünglichen Skript erforderlich waren.

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

Die Kombination dieser beiden Skripte ermöglicht die Übergabe von Parametern von Bash- an Gnuplot-Skripte, unabhängig von der Gnuplot-Version und im Grunde genommen in jedem * nix.

bp.
quelle
5

Sie könnten sogar etwas Muschelmagie machen, zB so:

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

Meine Implementierung ist etwas komplexer (z. B. das Ersetzen einiger magischer Token im sed-Aufruf, während ich bereits dabei bin ...), aber ich habe dieses Beispiel zum besseren Verständnis vereinfacht. Sie könnten es auch noch einfacher machen ... YMMV.

Stefan
quelle
4

In die Shell schreiben

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

und nacheinander die gewünschten Dateien. -persist wird verwendet, um den Gnuplot-Bildschirm so lange zu halten, wie der Benutzer ihn nicht manuell beendet.

Aniruddha Bera
quelle
In der Win7-Konsole scheint die Option -persist nicht zu funktionieren? Zum Beispiel gnuplot -persist -c "myscript.plt" "mydata.csv" "myoutput.png"funktioniert dieser Befehl einwandfrei und ich erhalte die Datei "myoutput.png" wie erwartet, aber der Gnuplot-Bildschirm wird nicht angezeigt (NO- exitBefehl in myscript.plt). Warum? Und wie wird der Gnuplot-Bildschirm in meinem Beispiel angezeigt?
Lyl
1

Ein weiterer Weg ist folgender:

Sie haben ein Gnuplot-Skript mit dem Namen scriptname.gp:

#!/usr/bin/gnuplot -p
# This code is in the file 'scriptname.gp'
EPATH = $0
FILENAME = $1 

plot FILENAME

Jetzt können Sie das Gnuplot-Skript scriptname.gpmit dieser verschlungenen Syntax aufrufen :

echo "call \"scriptname.gp\" \"'.'\" \"'data.dat'\"" | gnuplot 
verwechseln
quelle
0

@ vagobertos Antwort scheint meiner Meinung nach die beste zu sein, wenn Sie Positionsargumente benötigen , und ich muss eine kleine Verbesserung hinzufügen.

Vagobertos Vorschlag:

#!/usr/local/bin/gnuplot --persist

THIRD=ARG3
print "script name        : ", ARG0
print "first argument     : ", ARG1
print "third argument     : ", THIRD 
print "number of arguments: ", ARGC 

was aufgerufen wird von:

$ gnuplot -c script.gp one two three four five
script name        : script.gp
first argument     : one
third argument     : three
number of arguments: 5

für diese faulen Schreibmaschinen wie mich könnte man das Skript ausführbar machen ( chmod 755 script.gp)

Verwenden Sie dann Folgendes:

#!/usr/bin/env gnuplot -c

THIRD=ARG3
print "script name        : ", ARG0
print "first argument     : ", ARG1
print "third argument     : ", THIRD
print "number of arguments: ", ARGC

und führen Sie es aus als:

$ ./imb.plot a b c d
script name        : ./imb.plot
first argument     : a
third argument     : c
number of arguments: 4
Brett Holman
quelle