วิธีการแตกสตริงที่ยาวเป็นหลายบรรทัดในพร้อมต์ read -p ภายในซอร์สโค้ด?


19

/bin/shฉันจะเขียนสคริปต์การติดตั้งที่จะใช้เป็น

มีบรรทัดแจ้งให้ไฟล์:

read -p "goat can try change directory if cd fails to do so. Would you like to add this feature? [Y|n] " REPLY

ฉันต้องการแบ่งบรรทัดยาวเป็นหลายบรรทัดเพื่อไม่ให้มีเกิน 80 อักขระ ฉันกำลังพูดถึงบรรทัดภายในซอร์สโค้ดของสคริปต์ ไม่เกี่ยวกับบรรทัดที่จะพิมพ์จริงบนหน้าจอเมื่อสคริปต์ถูกดำเนินการ!

สิ่งที่ฉันได้ลอง:

  • วิธีการเริ่ม:

    read -p "goat can try change directory if cd fails to do so. " \
        "Would you like to add this feature? [Y|n] " REPLY

    Would you like to add this feature? [Y|n]นี้ไม่ได้ทำงานเพราะมันไม่ได้พิมพ์

  • แนวทางที่สอง:

    echo "goat can try change directory if cd fails to do so. " \
        "Would you like to add this feature? [Y|n] "
    read REPLY

    ใช้งานไม่ได้เช่นกัน มันพิมพ์ขึ้นบรรทัดใหม่หลังจากพรอมต์ การเพิ่ม-nตัวเลือกให้กับechoไม่ช่วย: เพียงพิมพ์:

    -n goat can try change directory if cd fails to do so. Would you like to add this feature? [Y|n]
    # empty line here
  • วิธีแก้ปัญหาปัจจุบันของฉันคือ

    printf '%s %s ' \
        "goat can try change directory if cd fails to do so." \
        "Would you like to add this feature? [Y|n] "
    read REPLY

และฉันสงสัยว่ามีวิธีที่ดีกว่า

จำไว้ว่าฉันกำลังมองหา/bin/shโซลูชันที่เข้ากันได้


1
ฉันขอแนะนำให้คุณ 1. ใช้เทอร์มินัลที่กว้างขึ้นและ / หรือหน้าต่างตัวแก้ไข (เช่นฉันใช้ 192 คอลัมน์ต่อ 51 บรรทัดเทอร์มินัลบนหน้าจอ 1440p ของฉัน - ดีมากสำหรับการปรับแต่งล็อกไฟล์และการแก้ไขซอร์สโค้ดเป็นกลุ่ม) ความจริงที่ว่าบางครั้งซอร์สโค้ดบรรทัดจะมีความยาวเกิน 80 อักขระซึ่งเป็นสิ่งที่หลีกเลี่ยงไม่ได้ ถ้าฉันใช้แบบอักษรขนาดเล็กฉันอาจมีเทอร์มินัลที่กว้างขึ้น แต่การตั้งค่าปัจจุบันของฉันคือการประนีประนอมระหว่างความกว้างและความชัดเจนที่ดี
cas

คำตอบ:


17

ก่อนอื่นให้เราอ่านค่าจากบรรทัดข้อความโดยใช้ตัวแปร:

text="line-1 line-2"             ### Just an example.
read -p "$text" REPLY

ด้วยวิธีนี้ปัญหาจะเกิดขึ้น: วิธีกำหนดสองบรรทัดให้กับตัวแปร

แน่นอนว่าความพยายามครั้งแรกในการทำเช่นนั้นคือ:

a="line-1 \
line-2"

เขียนว่า var aได้รับค่าline-1 line-2จริง

แต่คุณไม่ชอบการขาดการเยื้องที่สร้างนี้แล้วเราอาจพยายามอ่านบรรทัดลงใน var จาก here-doc (โปรดทราบว่าบรรทัดที่เยื้องในที่นี่ doc ต้องมีแท็บไม่ใช่ช่องว่าง ทำงานอย่างถูกต้อง):

    a="$(cat <<-_set_a_variable_
        line-1
        line-2
        _set_a_variable_
    )"
echo "test1 <$a>"

$aแต่ที่จะล้มเหลวเป็นจริงทั้งสองสายจะมีการเขียน วิธีแก้ไขปัญหาเพื่อรับเพียงหนึ่งบรรทัดอาจเป็น:

    a="$( echo $(cat <<-_set_a_variable_
        line 1
        line 2
        _set_a_variable_
        ) )"
echo "test2 <$a>"

นั่นคือปิด แต่สร้างปัญหาเพิ่มเติมอื่น ๆ

ทางออกที่ถูกต้อง

ความพยายามทั้งหมดข้างต้นจะทำให้ปัญหานี้ซับซ้อนยิ่งขึ้นซึ่งจำเป็นต้องมี

วิธีการขั้นพื้นฐานและเรียบง่ายมากคือ:

a="line-1"
a="$a line-2"
read -p "$a" REPLY

รหัสสำหรับตัวอย่างเฉพาะของคุณคือ (สำหรับเชลล์ที่readสนับสนุน-p):

#!/bin/dash
    a="goat can try change directory if cd fails to do so."
    a="$a Would you like to add this feature? [Y|n] "
# absolute freedom to indent as you see fit.
        read -p "$a" REPLY

สำหรับเชลล์อื่น ๆ ให้ใช้:

#!/bin/dash
    a="goat can try change directory if cd fails to do so."
    a="$a Would you like to add this feature? [Y|n] "
# absolute freedom to indent as you see fit.
        printf '%s' "$a"; read REPLY

@BinaryZebra ฉันรู้ ฉันเพิ่งแก้ไข "สำหรับเชลล์ใด ๆ " เนื่องจากเชลล์ไม่ได้อ่านทั้งหมดและไม่ใช่ทุกเชลล์ที่มี -p
terdon

@terdon เราทั้งคู่เห็นด้วยนั่นคือเหตุผลที่ขอบคุณ :-) ขอบคุณอีกครั้ง.

1

แบ็กสแลชที่ส่วนท้ายของบรรทัดอนุญาตให้มีความต่อเนื่องของคำสั่งมากกว่าหลายบรรทัดไม่ใช่ตัวแบ่งบรรทัดที่แท้จริงในเอาต์พุต

ตัวอย่างเช่นวิธีแรกของคุณกลายเป็นคำสั่ง

read -p "goat can try change directory if cd fails to do so. " "Would you like to add this feature? [Y|n] " REPLY

ฉันไม่แน่ใจว่าทำไมคุณต้องการอ่านเพื่อส่งออกหลายบรรทัด แต่ฉันจะใช้readสำหรับบรรทัดแจ้งให้และechoบรรทัดก่อนหน้า

ในการทำให้โค้ดอ่านได้ง่ายกว่าหลายบรรทัดอย่าปิด / เปิดคำพูดระหว่างบรรทัด

ลองสิ่งนี้:

read -p "goat can try change directory if cd fails to do so. \
Would you like to add this feature? [Y|n] " REPLY

ฉันไม่ต้องการให้พิมพ์สองบรรทัด! ฉันต้องการรหัสให้พอดีกับอักขระ 80 ตัวต่อบรรทัดในซอร์สโค้ดของสคริปต์ ! ขอบคุณสำหรับคำตอบ :) :)
Mateusz Piotrowski

ฉันไม่ชอบวิธีการที่คุณแนะนำเพราะไม่มีการเยื้อง ถ้าreadเยื้องของฉันในฟังก์ชั่นแล้ววิธีการของคุณดูเหมือนจะเลอะอ่านง่าย
Mateusz Piotrowski

1

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

read -p "goat can try change directory if cd fails to do so. \
Would you like to add this feature? [Y|n] " REPLY

คุณคิดว่าการเพิ่มบรรทัดใหม่หลังจากทุกบรรทัดจะเพิ่มความสามารถในการอ่านหรือไม่ เพราะฉันไม่ได้มองหาวิธีแทรก\nลงในพรอมต์ของฉัน ฉันแค่ต้องการแบ่งรหัสออกเป็นหลายบรรทัดเพื่อให้ทุกบรรทัดยาวได้ไม่เกิน 80 อักขระ
Mateusz Piotrowski

1
@MateuszPiotrowski โอ้นั่นทำให้เข้าใจได้มากกว่า ถ้าอย่างนั้นคำตอบของฉันก็ไม่มีประโยชน์ โปรดแก้ไขคำถามของคุณและชี้แจงว่าคุณต้องการแยกรหัสและไม่ส่งออก ฉันอยู่บนมือถือแล้ว แต่ฉันจะดูว่าฉันจะได้รับอะไรในวันพรุ่งนี้ได้ไหม
terdon

1
@MateuszPiotrowski เสร็จแล้วฉันได้เพิ่มเวอร์ชันการทำงานของสิ่งที่คุณเคยพยายาม
terdon

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