Kapan saya melakukannya
str="Hello World\n===========\n"
Saya juga \n
mencetaknya. Bagaimana saya bisa mendapatkan baris baru?
Kapan saya melakukannya
str="Hello World\n===========\n"
Saya juga \n
mencetaknya. Bagaimana saya bisa mendapatkan baris baru?
Jawaban:
Di dalamnya bash
Anda bisa menggunakan sintaks
str=$'Hello World\n===========\n'
Kutipan tunggal yang didahului oleh a $
adalah sintaks baru yang memungkinkan untuk memasukkan urutan escape dalam string.
printf
Builtin juga memungkinkan untuk menyimpan output yang dihasilkan ke variabel
printf -v str 'Hello World\n===========\n'
Kedua solusi tidak memerlukan subkulit.
Jika dalam hal-hal berikut Anda perlu mencetak string, Anda harus menggunakan tanda kutip ganda, seperti dalam contoh berikut:
echo "$str"
karena ketika Anda mencetak string tanpa tanda kutip, baris baru dikonversi menjadi spasi.
str=$'Hello World\n===========\n'
disebut sintaksis ? substitusi variabel?
zsh
dan ksh
; namun, ini BUKAN sesuai POSIX.
str=$"My $PET eats:\n$PET food"
? Pendekatan ini bekerja untuk tanda kutip ganda
Anda dapat menempatkan baris baru literal dalam tanda kutip tunggal (di shell gaya Bourne / POSIX).
str='Hello World
===========
'
Untuk string multiline, di sini dokumen sering kali nyaman. String diumpankan sebagai input ke perintah.
mycommand <<'EOF'
Hello World
===========
EOF
Jika Anda ingin menyimpan string dalam suatu variabel, gunakan cat
perintah dalam substitusi perintah. Karakter baris baru di akhir string akan dilucuti oleh substitusi perintah. Jika Anda ingin mempertahankan baris baru, letakkan sumbat di ujungnya dan cabut kemudian. Di shell yang sesuai dengan POSIX, Anda dapat menulis str=$(cat <<'EOF'); str=${str%a}
diikuti oleh heredoc yang tepat, tetapi bash membutuhkan heredoc untuk muncul sebelum tanda kurung penutup.
str=$(cat <<'EOF'
Hello World
===========
a
EOF
); str=${str%a}
Di ksh, bash, dan zsh, Anda dapat menggunakan $'…'
formulir yang dikutip untuk memperluas garis miring terbalik di dalam tanda kutip.
str=$'Hello World\n===========\n'
str=$(cat <<'EOF')
tidak berfungsi sebagaimana mestinya .. )
Kebutuhan untuk ditempatkan pada baris berikutnya setelah akhir-dok EOF
.. tetapi meskipun demikian, ia kehilangan baris tambahan karena Command Pengganti.
\n
instance bash
ketika mengambil-doc di sini dalam variabel, pertimbangkan IFS= read -r -d '' str <<'EOF'...
sebagai alternatif untuk pendekatan stopper (lihat jawaban saya).
Apakah Anda menggunakan "gema"? Coba "echo -e".
echo -e "Hello World\n===========\n"
echo
akan secara otomatis menambahkannya, kecuali jika Anda menentukan -n. (Namun, beban utama dari pertanyaan, adalah bagaimana memasukkan baris baru ini ke dalam variabel).
bash
, echo -e
tidak bekerja pada OS X - itu karena echo
merupakan bash builtin (bukan executable eksternal) dan bahwa builtin tidak mendukung -e
. (Sebagai bawaan, itu harus bekerja pada semua platform yang dijalankan bash; secara kebetulan, echo -e
bekerja di dalam ksh
dan zsh
juga). Sebaliknya, utilitas eksternalecho
pada OS X - /bin/echo
- memang tidak mendukung -e
.
Jika Anda membutuhkan baris baru dalam skrip Anda berkali-kali, Anda bisa mendeklarasikan variabel global yang memegang baris baru. Dengan begitu Anda bisa menggunakannya dalam string yang dikutip ganda (ekspansi variabel).
NL=$'\n'
str="Hello World${NL} and here is a variable $PATH ===========${NL}"
$''
perlu subkulit?
"My dog eats:${NL}dog food"
Untuk melengkapi jawaban hebat yang sudah ada:
Jika Anda menggunakan bash
dan lebih suka menggunakan baris baru untuk keterbacaan , read
adalah opsi lain untuk menangkap dokumen di sini dalam variabel , yang (seperti solusi lain di sini) tidak memerlukan penggunaan subkulit.
# Reads a here-doc, trimming leading and trailing whitespace.
# Use `IFS= read ...` to preserve it (the trailing \n, here).
read -r -d '' str <<'EOF' # Use `IFS= read ...` to preserve the trailing \n
Hello World
===========
EOF
# Test: output the variable enclosed in "[...]", to show the value's boundaries.
$ echo "$str"
[Hello World
===========]
-r
memastikan bahwa read
tidak menginterpretasikan input (secara default, itu akan memperlakukan backslash khusus, tetapi itu jarang diperlukan).
-d ''
menetapkan pembatas "record" menjadi string kosong, menyebabkan read
pembacaan seluruh input sekaligus (bukan hanya satu baris).
Perhatikan bahwa dengan meninggalkan $IFS
(pemisah bidang internal) pada pengaturan standarnya, $' \t\n'
(spasi, tab, baris baru), spasi spasi apa pun yang memimpin dan tertinggal dipangkas dari nilai yang ditetapkan $str
, yang mencakup baris baru di sini-doc.
(Perhatikan bahwa meskipun tubuh di sini-doc mulai pada baris setelah pembatas mulai (di 'EOF'
sini), itu tidak mengandung baris baru yang memimpin ).
Biasanya, ini adalah perilaku yang diinginkan, tetapi jika Anda ingin yang mengikuti baris baru, gunakan IFS= read -r -d ''
bukan hanya read -r -d ''
, tetapi perhatikan bahwa spasi spasi apa pun yang memimpin dan tertinggal kemudian dipertahankan.
(Perhatikan bahwa menambahkan IFS=
langsung ke read
perintah berarti bahwa penugasan hanya berlaku selama perintah itu saja, sehingga tidak perlu mengembalikan nilai sebelumnya.)
Menggunakan dokumen-sini juga memungkinkan Anda untuk menggunakan indentasi opsional untuk mematikan string multiline agar mudah dibaca:
# Caveat: indentation must be actual *tab* characters - spaces won't work.
read -r -d '' str <<-'EOF' # NOTE: Only works if the indentation uses actual tab (\t) chars.
Hello World
===========
EOF
# Output the variable enclosed in "[...]", to show the value's boundaries.
# Note how the leading tabs were stripped.
$ echo "$str"
[Hello World
===========]
Menempatkan di -
antara <<
dan pembuka di sini-doc pembatas ( 'EOF'
, di sini) menyebabkan karakter tab utama dihapus dari badan di sini-doc dan bahkan pembatas penutup, tetapi perlu dicatat bahwa ini hanya bekerja dengan karakter tab yang sebenarnya , bukan spasi, jadi jika Anda Editor menerjemahkan penekanan tombol tab ke spasi, diperlukan kerja ekstra.
Anda perlu melakukannya dengan cara ini:
STR=$(echo -ne "Hello World\n===========\n")
Memperbarui:
Seperti yang ditunjukkan Fred, dengan cara ini Anda akan kehilangan jejak "\ n". Untuk menetapkan variabel dengan urutan backslash diperluas, lakukan:
STR=$'Hello World\n===========\n\n'
mari kita mengujinya:
echo "[[$STR]]"
beri kami sekarang:
[[Hello World
===========
]]
Perhatikan, bahwa $ '' berbeda dari $ "". Yang kedua melakukan terjemahan sesuai dengan lokal saat ini. Untuk deital, lihat bagian QUOTING di man bash
.
#!/bin/bash
result=""
foo="FOO"
bar="BAR"
result+=$(printf '%s' "$foo")$'\n'
result+=$(printf '%s' "$bar")$'\n'
echo "$result"
printf '%s' "$result"
keluaran:
FOO
BAR
FOO
BAR
result+=$foo$'\n'
? $(printf %s "$foo")
akan memangkas trailing karakter baris baru $foo
jika ada.