Bagaimana memecah string yang panjang menjadi beberapa baris dalam prompt read -p dalam kode sumber?

18

Saya sedang menulis skrip instalasi yang akan dijalankan sebagai /bin/sh.

Ada baris yang meminta file:

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

Saya ingin memecah garis panjang ini menjadi banyak garis sehingga tidak ada yang melebihi 80 karakter. Saya sedang berbicara tentang baris dalam kode sumber skrip; bukan tentang garis yang benar-benar dicetak di layar ketika skrip dieksekusi!

Apa yang saya coba:

  • Pendekatan Frist:

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

    Ini tidak berfungsi karena tidak mencetak Would you like to add this feature? [Y|n].

  • Pendekatan kedua:

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

    Tidak berfungsi juga. Ini mencetak baris baru setelah prompt. Menambahkan -nopsi ke echotidak membantu: hanya mencetak:

    -n goat can try change directory if cd fails to do so. Would you like to add this feature? [Y|n]
    # empty line here
  • Solusi saya saat ini adalah

    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

dan saya bertanya-tanya apakah ada cara yang lebih baik.

Ingatlah bahwa saya mencari /bin/shsolusi yang kompatibel.

Mateusz Piotrowski
sumber
1
Saya menyarankan agar Anda 1. menggunakan terminal yang lebih luas dan / atau jendela editor (misalnya saya menggunakan terminal 192 kolom dengan 51 baris pada monitor 1440p saya - bagus untuk tailing file log dan mengedit kode sumber dalam vim) dan 2. belajar untuk menerima fakta bahwa kadang-kadang baris kode sumber akan lebih dari 80 karakter - itu tidak bisa dihindari. Jika saya menggunakan font yang lebih kecil, saya bisa memiliki terminal yang lebih lebar tetapi pengaturan saya saat ini adalah kompromi yang baik antara lebar dan keterbacaan.
cas

Jawaban:

16

Pertama-tama, mari kita pisahkan membaca dari baris teks dengan menggunakan variabel:

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

Dengan cara ini masalahnya menjadi: Cara menetapkan dua baris ke variabel.

Tentu saja, upaya pertama untuk melakukan itu, adalah:

a="line-1 \
line-2"

Ditulis seperti itu, var abenar-benar mendapatkan nilai line-1 line-2.

Tapi Anda tidak suka kurangnya indentasi yang diciptakan ini, well, maka kita dapat mencoba membaca baris ke var dari sini-doc (perlu diketahui bahwa baris indentasi di dalam sini-doc membutuhkan tab, bukan spasi, untuk bekerja dengan benar):

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

Tapi itu akan gagal karena sebenarnya dua baris ditulis untuk $a. Solusi untuk mendapatkan hanya satu baris mungkin:

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

Itu dekat, tetapi menciptakan masalah tambahan lainnya.

Solusi yang benar.

Semua upaya di atas hanya akan membuat masalah ini lebih rumit dari yang seharusnya.

Pendekatan yang sangat mendasar dan sederhana adalah:

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

Kode untuk contoh spesifik Anda adalah (untuk setiap shell yang readmendukungnya -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

Untuk semua kerang lainnya, gunakan:

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

sumber
@ Binzebra saya tahu. Saya baru saja mengoreksi "untuk semua shell" karena tidak semua shell telah membaca dan tidak semua yang memiliki -p.
terdon
@terdon Kami berdua sepakat. Itulah alasannya untuk terima kasih :-). Terima kasih lagi.
1

Garis miring terbalik pada akhir baris memungkinkan kelanjutan dari perintah melalui beberapa baris, bukan garis putus aktual dalam output.

Jadi pendekatan pertama Anda, misalnya, menjadi perintah

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

Saya tidak yakin mengapa Anda ingin membaca untuk menampilkan beberapa baris, tetapi saya hanya akan menggunakan readuntuk baris prompt dan echobaris sebelumnya.

Agar kode lebih mudah dibaca dari banyak baris, jangan tutup / buka tanda kutip antar baris.

Coba ini:

read -p "goat can try change directory if cd fails to do so. \
Would you like to add this feature? [Y|n] " REPLY
Ian Petts
sumber
Saya tidak ingin mencetak dua baris! Saya hanya ingin kode tersebut sesuai dengan 80 karakter per baris dalam kode sumber skrip ! Terima kasih atas jawabannya :)
Mateusz Piotrowski
Saya tidak suka pendekatan yang Anda sarankan karena tidak ada lekukan. Jika saya readindentasi dalam fungsi maka pendekatan Anda tampaknya mengacaukan keterbacaan.
Mateusz Piotrowski
1

Saya menemukan pendekatan @ BinaryZebra menggunakan variabel untuk menjadi lebih bersih, tetapi Anda juga bisa melakukannya dengan cara yang Anda coba. Anda hanya perlu menjaga jeda baris di dalam tanda kutip:

read -p "goat can try change directory if cd fails to do so. \
Would you like to add this feature? [Y|n] " REPLY
terdon
sumber
Apakah Anda berpikir bahwa menambahkan baris baru setelah setiap baris akan meningkatkan keterbacaan? Karena saya tidak mencari cara untuk memasukkan \nprompt saya. Saya hanya ingin memecah kode menjadi beberapa baris sehingga setiap baris paling panjang 80 karakter.
Mateusz Piotrowski
1
@MateuszPiotrowski oh, itu jauh lebih masuk akal. Maka jawaban saya tidak terlalu berguna. Harap edit pertanyaan Anda dan jelaskan bahwa Anda ingin membagi kode dan bukan hasilnya. Saya menggunakan ponsel sekarang tetapi saya akan melihat apakah saya dapat membuat sesuatu besok.
terdon
1
@MateuszPiotrowski selesai, saya menambahkan versi yang berfungsi dari apa yang awalnya Anda coba.
terdon
0

Bagaimana dengan ini saja:

#! / bin / bash
baca -p "Halo
dunia
ini adalah sebuah
multi-line
prompt: "PROMPT
echo $ PROMPT

Desmond
sumber
Bagaimana Anda membuat indentasi?
Mateusz Piotrowski