it-swarm-id.com

Cara menambahkan baris baru ke dalam variabel dalam skrip bash

Kapan saya melakukannya

str="Hello World\n===========\n"

Saya mendapatkan \n dicetak juga. Bagaimana saya bisa mendapatkan baris baru?

80
Jiew Meng

Dalam bash Anda dapat menggunakan sintaks

str=$'Hello World\n===========\n'

Kutipan tunggal didahului oleh $ adalah sintaks baru yang memungkinkan untuk memasukkan urutan pelarian dalam string.

Juga printf builtin memungkinkan untuk menyimpan hasil yang dihasilkan ke variabel

printf -v str 'Hello World\n===========\n'

Kedua solusi tidak memerlukan subkulit.

Jika dalam 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.

90
enzotib

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 variabel, gunakan perintah cat 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 sesudahnya. 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 meluaskan garis miring terbalik di dalam tanda kutip.

str=$'Hello World\n===========\n'

Apakah Anda menggunakan "echo"? Coba "echo -e".

echo -e "Hello World\n===========\n"
9
Mike

Jika Anda memerlukan 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}"
6
pihentagy

Untuk melengkapi jawaban hebat yang sudah ada:

Jika Anda menggunakan bash dan Anda lebih suka menggunakan baris baru yang sebenarnya untuk keterbacaan, read adalah pilihan lain untuk menangkap sebuah here-doc dalam sebuah 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 '' mengatur pembatas "record" ke string kosong, menyebabkan read untuk membaca seluruh input sekaligus (bukan hanya sebuah garis tunggal).

Perhatikan bahwa dengan meninggalkan $IFS (pemisah bidang internal) secara default, $' \t\n' (spasi, tab, baris baru), sembarang spasi spasi awal dan akhir dipangkas dari nilai yang diberikan pada $str, yang termasuk baris baru di sini-doc.
(Perhatikan bahwa meskipun dokumen di sini dimulai pada baris setelah pembatas awal ('EOF' di sini), tidak tidak berisi baris baru ).

Biasanya, ini adalah perilaku yang diinginkan, tetapi jika Anda ingin mengikuti baris baru, gunakan IFS= read -r -d '' bukan hanya read -r -d '', tetapi perhatikan bahwa sembarang spasi spasi awal dan akhir kemudian dipertahankan.
(Perhatikan bahwa menambahkan IFS=  langsung ke perintah read berarti bahwa penugasan hanya berlaku selama perintah itu saja, jadi tidak perlu mengembalikan nilai sebelumnya.)


Menggunakan di sini-doc juga memungkinkan Anda untuk opsional menggunakan indentasi 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 - antara << dan pembatas di sini-doc ('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 aktual karakter tab, bukan spasi, jadi jika editor Anda menerjemahkan penekanan tombol tab menjadi spasi, diperlukan kerja ekstra.

3
mklement0

Dari semua diskusi, berikut adalah cara paling sederhana bagi saya:

bash$ str="Hello World
==========="
bash$ echo "$str"
Hello World
===========

Perintah echo harus menggunakan tanda kutip ganda.

3
kholis