มีวิธีที่จะหลีกเลี่ยงอัญประกาศเดี่ยวในเชลล์หรือไม่?


11

เช่น. ฉันต้องการพูด

perl -e 'print '"'"'Hello, world!'"'"', "\n";'

มีวิธีที่น่าอึดอัดใจน้อยกว่าในการทำเช่นหนีคำเดียว?

ใช่ฉันรู้ว่าฉันสามารถเขียนได้

perl -e 'print q[Hello, world!], "\n"'
perl -e 'print "Hello, world!\n"'

แต่คำถามนี้เกี่ยวกับการอ้างถึงในเชลล์ไม่ใช่ใน Perl

ฉันสนใจที่จะทำมันในbashและcshในตอนแรก

คำตอบ:


9

เดนนิสชี้ให้เห็นถึงทางเลือกปกติในคำตอบของเขา (สตริงที่มีคำพูดเดี่ยวสองครั้ง, สองครั้งในหนึ่งเดียว, รวมกับเครื่องหมายคำพูดเดียวที่หลบหนีคุณพูดถึงผู้ประกอบการเสนอราคา Perl ที่ปรับแต่งได้แล้ว) แต่นี่อาจเป็นคำตอบโดยตรง สำหรับ.

ในเชลล์ที่มีลักษณะคล้ายบอร์น (sh, ksh, ash, dash, bash, zsh, ฯลฯ ) สตริงที่ยกมาเดี่ยวเป็นตัวอักษรที่สมบูรณ์ สิ่งนี้ทำให้ง่ายต่อการรวมอักขระที่เชลล์จะจัดการเป็นพิเศษโดยไม่ต้องหลบหนี แต่หมายความว่าอักขระตัวอัญประกาศเดี่ยวไม่สามารถรวมอยู่ในสตริงที่ยกมาเดี่ยวได้

ฉันปฏิเสธแม้แต่คิดเกี่ยวกับเปลือก csh-type เนื่องจากพวกเขาจะแตกในเรื่องอื่น ๆ อย่างเต็มที่ (ดูการเขียนโปรแกรม Csh ถือว่าเป็นอันตราย )


ขอบคุณ. "นี่เป็นไปไม่ได้" - มันเป็นคำตอบที่ฉันคาดไว้ :) แม้ว่าฉันหวังว่ามันจะเป็นเอกสารที่อุทิศให้กับบทนี้
codeholic

แตกต่างจากใน Perl, เชลล์เหมือนบอร์นที่นี่เอกสารมีประโยชน์โดยตรงสำหรับการป้อนข้อมูลผ่าน stdin คุณสามารถใส่เครื่องหมายคำพูดเดี่ยวลงไปได้ นอกจากนี้คุณยังสามารถเปิดใช้งานโหมด "ที่แท้จริง" ของเอกสารที่นี่โดยการอ้างคำว่า: blah <<\EOF … EOF(เช่น) นอกจากนี้คุณยังสามารถใช้และ<<'EOF' <<"EOFพวกเขาทั้งหมดหมายถึงเอกสารตามตัวอักษรที่นี่ (ไม่เหมือน Perl) หากคุณได้รับการพิจารณาจริง ๆ คุณสามารถทำได้blah "$(cat<<\EOF … EOF )" other args(ใช้การขึ้นบรรทัดใหม่ที่ฉันได้เขียนช่องว่างในการทดแทนคำสั่ง; ksh และ zsh สามารถทำได้โดยไม่มีแมวคนอื่น ๆ ต้องการมัน) แต่มันจะคุ้มหรือไม่
Chris Johnsen

เพียงแค่ต้องการที่จะทราบว่าคำพูดเดียว zsh ไม่ได้ค่อนข้างตามตัวอักษร Zsh จะพยายามตีความ '\ U' ที่ใดก็ได้ในสตริงที่ยกมาเดี่ยวเป็นรหัสอักขระเช่นecho '\U0000068\U000069'echoes 'hi' ไม่แน่ใจว่าทำไมแม้ว่าจะเป็นบั๊กในเชลล์
Matthew

1
@Matthew: การตีความของ\Uในกรณีนั้นจะถูกทำโดยคำสั่งechoในตัว(พฤติกรรมนี้สามารถควบคุมได้โดย-Eหรือตัวเลือก BSD_ECHO และ-e) คุณจะเห็นว่าสตริงตัวอักษรถูกส่งผ่าน (และไม่ตีความเป็นอย่างอื่น) ในคำสั่งอื่น ๆ ; printf %s\\n '\U0000068\U000069'เช่น
Chris Johnsen

@ChrisJohnsen ขอบคุณฉันยังใหม่กับ zsh และไม่ได้ตระหนักถึงสิ่งนี้ แต่คุณพูดถูก หน้าคนบอกฉัน -e เป็นค่าเริ่มต้น แต่ zsh จะต้องแทนที่นั้น
Matthew

5

สำหรับฉันตัวอย่างทั้งหมดของคุณผลิต:

สวัสดีชาวโลก!

และสิ่งนี้ก็เช่นกัน

perl -e 'print "Hello, world!", "\n";'

และนี่:

perl -e 'print '\''Hello, world!'\'', "\n";'

คุณช่วยอธิบายสิ่งที่คุณพยายามจะทำอย่างไร

ในเชลล์เช่น Bash หากคุณต้องการพิมพ์เครื่องหมายอัญประกาศเป็นส่วนหนึ่งของสตริงอัญประกาศประเภทหนึ่งจะหนีจากกัน

$ echo '"Hello, world!"'
"Hello, world!"
$ echo "'Hello, world!'"
'Hello, world!'

แก้ไข:

นี่คือวิธีอื่น:

$ perl -e 'print "\047Hello, world!\047", "\n";'
'Hello, world!'
$ echo -e "\047Hello, world! \047"
'Hello, world! '

ช่องว่างหลังเครื่องหมายอัศเจรีย์หลีกเลี่ยงข้อผิดพลาดการขยายประวัติ ฉันสามารถทำได้set +Hแทน


1

ไม่แน่ใจว่าการแก้ไขคำตอบก่อนหน้าของฉันจะปรากฏขึ้นหรือไม่:

การวางเช่นเดียวกับคำตอบใหม่:

วิธีอื่น:

เมื่อฉันลองวิธีแก้ปัญหาของคุณฉันยังคงไม่สามารถ 'พิมพ์ได้

แต่ฉันเอาคิวจากโซลูชันของคุณและลองต่อไปนี้:

$ perl -e '$foo = chr(39); print "${foo}Hello, world ${foo}", "\n";'
'Hello, world '

ค่า ASCII ของ 'คือ 39

ฉันต้องการสิ่งนี้เพื่อทำการแก้ไขแบบอินไลน์ไปยังกลุ่มของไฟล์เพื่อเพิ่ม 'ในสถานที่ที่น่าสนใจ


1

เอกสารที่นี่เป็นวิธีที่ดีที่สุดที่จะไม่สนใจการหลบหนี:

$ cat <<EOF
my $var = "Hello";
print $text, ', world!', "\n";'
EOF

คุณอาจ inibit expantion ทั้งหมดโดยใช้เอกสารที่ยกมาที่นี่:

$ cat <<'EOF'
my $var = "Hello";
print $text, ', world!', "\n";'
EOF

หากคุณต้องการส่งเป็นอาร์กิวเมนต์แทนอินพุตคุณสามารถใช้ xargs:

$ xargs -0 <<'EOF' perl -e
my $var = "Hello";
print $text, ', world!', "\n";'
EOF

0

ฉันไม่ทราบว่ามีตัวเลือกในการทำเช่นนี้ในทุบตี แต่ด้วย zsh คุณสามารถใช้''หลังจากเปิดRC_QUOTESตัวเลือก (ฉันขอแนะนำให้ลอง zsh ซึ่งส่วนใหญ่ใช้งานได้กับ bash และสามารถเลียนแบบ bash เพื่อความเข้ากันได้มากขึ้น)

ด้วยการทุบตี (และยังคงใช้เวลาส่วนใหญ่กับ zsh) ผมเพียงแค่ใช้เพราะมันง่ายต่อการอ่านกว่า'\'''"'"'

ฉันไม่รู้จริง ๆ ว่าจะทำอย่างไรใน csh


-1

คุณสามารถใช้ \ 'และ \ "เพื่อยกเว้นเครื่องหมายคำพูดด้วย perl หากใช้ภายในเป็นส่วนหนึ่งของสคริปต์ perl ฉันไม่แน่ใจว่าบรรทัดคำสั่งจะยอมรับสิ่งนั้นหรือไม่คุณสามารถลองดูและใช้งานได้


3
ถ้ามันง่ายมากฉันจะไม่ถาม คุณสามารถลองและดูว่าใช้ได้หรือไม่ก่อนโพสต์คำตอบ
codeholic
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.