จะส่งผ่านอาร์กิวเมนต์บรรทัดคำสั่งไปยัง gnuplot ได้อย่างไร


148

ฉันต้องการใช้ gnuplot วาดรูปจากแฟ้มข้อมูลพูดfoo.data ขณะนี้ฉัน hardcoded ชื่อไฟล์ข้อมูลในไฟล์คำสั่งพูด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'
mgilson

10
สำหรับคนสะดุดข้ามตอนนี้ความคิดเห็น mgilson และ Gnuplot 4.6 patchlevel 3 ต้องแทนif (!exists("filename") if ! exists("filename")
Sam Mussmann

วิธีการทำสิ่งเดียวกันใน windows?
padawan

6
@Chong: สตริงทั้งสองเข้าด้วยกันหรือให้แต่ละคนใน-eการโต้แย้งเช่นหรือ-e "filename='default.data'; foo='bar'" -e "filename='default.data'" -e "foo='bar"'
Thor

1
หมายเหตุ:-e ...ตัวเลือกที่มีนำหน้าชื่อไฟล์ อันที่จริงจากman gnuplotเราสามารถอ่าน: -eรายการ "คำสั่ง" รันคำสั่งที่ร้องขอก่อนที่จะโหลดไฟล์ของท่านต่อไป .
Hastur

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

@Edgar Bonet: ต้องการรุ่น gnuplot ใดสำหรับสิ่งนี้ ดูเหมือนจะไม่ได้ผลกับเครื่อง y ที่ใช้ 4.2 ...
Bjoern

สวัสดี @Bjoern! ฉันใช้ Gnuplot 4.6 แต่นี่ไม่ใช่คุณสมบัติ Gnuplot มันเป็นคุณสมบัติของเชลล์: name=value commandบอกเชลล์ให้รันคำสั่งด้วยตัวแปรเฉพาะในสภาพแวดล้อมของมัน ฉันใช้ทุบตี 4.3.11 แต่ฉันเชื่อว่าเป็นคุณสมบัติเชลล์ที่ใช้กันทั่วไป
Edgar Bonet

23

คำตอบของ Jari Laamanen คือทางออกที่ดีที่สุด ฉันต้องการอธิบายวิธีใช้พารามิเตอร์อินพุตมากกว่า 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

อย่างที่คุณเห็นพารามิเตอร์เพิ่มเติมจะถูกส่งผ่านด้วยเครื่องหมายทวิภาคกึ่ง (เช่นในสคริปต์ทุบตี) แต่ตัวแปรสตริงจะต้องถูกหุ้มด้วย '' (ไวยากรณ์ gnuplot, ไวยากรณ์ไม่ใช่ Bash)


1
สำหรับ gnuplot นั้นไม่สำคัญว่าคุณจะใช้'หรือใช้"กับสตริง เครื่องหมายคำพูดด้านนอกรอบ ๆ-eอาร์กิวเมนต์ต้อง"มีการแทนที่ตัวแปร bash ต่อไปนี้ยังใช้งานได้ดี:OUTPUT=foobar; gnuplot -e "output=\"$OUTPUT\"; print output"
Christoph

ขอบคุณที่ยืนยันว่าฉันสามารถใช้ semi colons เพื่อแยกคำสั่ง ไม่มีคำตอบอื่นใดที่แสดงสิ่งนี้
tommy.carstensen

14

คุณอาจใช้เคล็ดลับในสภาพแวดล้อม unix / linux:

  1. ในโปรแกรม gnuplot: plot "/ 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) shim ด้านล่างแก้ไขปัญหานี้ได้โดยไม่ต้องเปลี่ยนแปลงสคริปต์ต้นฉบับ

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

และไฟล์ที่คุณต้องการอย่างต่อเนื่อง - ผู้ใช้ใช้ในการทำให้หน้าจอ gnuplot คงอยู่ตราบใดที่ผู้ใช้ไม่ออกจากมันด้วยตนเอง


ในคอนโซล Win7 ตัวเลือก - ผู้ใช้ดูเหมือนจะไม่ทำงานใช่ไหม ตัวอย่างเช่นgnuplot -persist -c "myscript.plt" "mydata.csv" "myoutput.png"คำสั่งนี้ทำงานได้ถูกต้องและฉันได้รับไฟล์ "myoutput.png" ตามที่คาดไว้ แต่หน้าจอ gnuplot ไม่ปรากฏขึ้น ( exitคำสั่งNO ใน myscript.plt) ทำไม? และวิธีทำให้หน้าจอ gnuplot แสดงในตัวอย่างของฉัน
lyl

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 ที่ดีที่สุดหากคุณต้องการข้อโต้แย้งตำแหน่งและฉันมีการปรับปรุงเล็กน้อยเพื่อเพิ่ม

ข้อเสนอแนะของ 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
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.