วิธีระบุตัวแปรเชลล์หลายบรรทัด


123

ฉันได้เขียนคำถาม:

function print_ui_hosts
{
local sql = "select ........."
print_sql "$ sql"
}

sql ท้องถิ่น - สตริงที่ยาวมาก ไม่มีการจัดรูปแบบข้อความค้นหา ฉันจะแยกสตริงออกเป็นหลายบรรทัดได้อย่างไร


4
shellคุยอะไรกันดีที่นี่? ควรbatchจะเป็นbashหรือคุณมาจากด้านมืดจริงๆ?
Chris Seymour

1
ถ้านี่คือเปลือก / ทุบคุณไม่ควรล้อมรอบ=ด้วยช่องว่าง
Nik O'Lai

คำตอบ:


139

ใช้readกับ heredoc ดังที่แสดงด้านล่าง:

read -d '' sql << EOF
select c1, c2 from foo
where c1='something'
EOF

echo "$sql"

52
โปรดทราบว่าreadจะมีรหัสทางออกเป็น 1 ในสถานการณ์นี้ หากมีความสำคัญ (เช่นคุณกำลังใช้งานอยู่set -e) คุณจะต้องเพิ่ม|| trueที่ท้ายบรรทัดแรก
chepner

4
set -eออกจากเชลล์หากคำสั่งมีสถานะการออกที่ไม่ใช่ศูนย์ "ไม่คาดคิด" โดย "ไม่คาดคิด" หมายความว่ามันทำงานในบริบทที่คุณไม่ได้ดูสถานะการออกเป็นพิเศษ falseตัวอย่างเช่นโดยตัวมันเองจะออกจากเชลล์ false || trueจะไม่เนื่องจากคุณกำลังคาดการณ์สถานะการออกที่ไม่ใช่ศูนย์โดยการระบุคำสั่งอื่นเพื่อรันหากครั้งแรกล้มเหลว
chepner

1
ปัญหาเกี่ยวกับ set -e และการอ่าน (ดูแบบฝึกหัดสุดท้าย) มีการอธิบายโดยละเอียดที่นี่: mywiki.wooledge.org/BashFAQ/105
Niklas Peter

5
มา-d ' 'ทำอะไรที่นี่?
hg_git

3
@hg_git บอกreadไม่หยุดอ่านเมื่อเจอขึ้นบรรทัดใหม่.
Cyker

172

เพียงแค่ใส่บรรทัดใหม่เมื่อจำเป็น

sql="
SELECT c1, c2
from Table1, Table2
where ...
"

เชลล์จะมองหาเครื่องหมายคำพูดปิด


7
ไม่ใช่ทางออกที่ดีหากแบบสอบถาม sql มีเครื่องหมายอัญประกาศคู่ คุณจะต้องหนีพวกเขาและมันจะยุ่ง
dogbane

13
@dogbane doublequotes ไม่ค่อยปรากฏในภาษา SQL ส่วนใหญ่ดังนั้นในทางปฏิบัติสิ่งนี้จึงสะอาด
Iain Samuel McLean Elder

4
จากนั้นตัดสตริงด้วยเครื่องหมายคำพูดเดี่ยว
tripleee

ไม่แน่ใจว่าทำไมคุณถึงต้องการหรือต้องการตัวแบ่งสายนำ สำหรับใบสมัครของฉันฉันไม่ได้เริ่มต้นด้วยsql="SELECT c2, c2
bhfailor

1
ตลกที่ดูเหมือนง่ายเกินไปที่จะเป็นจริง FYI หากต้องการเพิ่ม DQ เพียงแค่สร้างตัวแปร DQ = '\ "' จากนั้นอ้างอิงในคำสั่งด้วย $ {DQ}
Timothy C. Quinn

70

ฉันต้องการให้คำตอบเพิ่มเติมหนึ่งคำในขณะที่คำตอบอื่น ๆ ก็เพียงพอแล้วในกรณีส่วนใหญ่

ฉันต้องการเขียนสตริงในหลาย ๆ บรรทัด แต่เนื้อหาจำเป็นต้องเป็นบรรทัดเดียว

sql="                       \
SELECT c1, c2               \
from Table1, ${TABLE2}      \
where ...                   \
"

ฉันขอโทษถ้าเรื่องนี้ไม่ตรงประเด็นเล็กน้อย (ฉันไม่ต้องการสิ่งนี้สำหรับ SQL) อย่างไรก็ตามโพสต์นี้ปรากฏขึ้นในผลลัพธ์แรกเมื่อค้นหาตัวแปรเชลล์หลายบรรทัดและดูเหมือนว่าคำตอบเพิ่มเติมจะเหมาะสม


1
แม้จะไม่มีเนื้อหาของฉันออกมาเลยแม้แต่บรรทัดเดียว
papiro

12
@papiro ลองecho "$sql"แทนecho $sql.
Michael Mol

@MichaelMol - ประมาณสองทศวรรษหลังจากที่ฉันติดตั้ง Linux ครั้งแรกและฉันยังคงเรียนรู้สิ่งใหม่ ๆ ขอบคุณสำหรับ "เคล็ดลับ" นี้
Seth

6

ขอบคุณคำตอบของ dimo414 สำหรับคำถามที่คล้ายกันสิ่งนี้แสดงให้เห็นว่าโซลูชันที่ยอดเยี่ยมของเขาทำงานอย่างไรและแสดงให้เห็นว่าคุณสามารถมีเครื่องหมายคำพูดและตัวแปรในข้อความได้อย่างง่ายดายเช่นกัน:

ตัวอย่างผลลัพธ์

$ ./test.sh

The text from the example function is:
  Welcome dev: Would you "like" to know how many 'files' there are in /tmp?

  There are "      38" files in /tmp, according to the "wc" command

test.sh

#!/bin/bash

function text1()
{
  COUNT=$(\ls /tmp | wc -l)
cat <<EOF

  $1 Would you "like" to know how many 'files' there are in /tmp?

  There are "$COUNT" files in /tmp, according to the "wc" command

EOF
}

function main()
{
  OUT=$(text1 "Welcome dev:")
  echo "The text from the example function is: $OUT"
}

main

5

readไม่ส่งออกตัวแปร (ซึ่งเป็นสิ่งที่ดีเกือบตลอดเวลา) นี่เป็นทางเลือกที่สามารถส่งออกได้ในคำสั่งเดียวสามารถเก็บรักษาหรือละทิ้งบรรทัดฟีดและอนุญาตให้ผสมรูปแบบการอ้างอิงได้ตามต้องการ ใช้ได้กับ bash และ zsh

oneLine=$(printf %s \
    a   \
    " b "   \
    $'\tc\t'    \
    'd '    \
)
multiLine=$(printf '%s\n' \
    a   \
    " b "   \
    $'\tc\t'    \
    'd '    \
)

ฉันยอมรับว่าความจำเป็นในการอ้างถึงทำให้ SQL น่าเกลียด แต่มันตอบคำถาม (โดยทั่วไปมากกว่า) ในชื่อเรื่อง

ผมใช้แบบนี้

export LS_COLORS=$(printf %s    \
    ':*rc=36:*.ini=36:*.inf=36:*.cfg=36:*~=33:*.bak=33:*$=33'   \
    ...
    ':bd=40;33;1:cd=40;33;1:or=1;31:mi=31:ex=00')

ในไฟล์ที่มาจากทั้ง my .bashrcและ.zshrc.

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