Cara menambahkan baris baru saat menggunakan gema


42

Mengapa perintah berikut tidak memasukkan baris baru dalam file yang dihasilkan dan apa solusinya?

$ echo "Line 1\r\nLine2" >> readme.txt

$ cat readme.txt 
Line 1\r\nLine2

6
Apakah echowajib? Anda dapat menggunakan printf.
Archemar

Saya tidak tahu tentang printf, dengan printf berfungsi: P ... lalu apa fungsinya jika tidak bekerja dengan gema?
Saeid Yazdani

Apakah \rtermasuk dalam output atau itu bagian dari CRLFbaris baru?
cuonglm

9
Ada banyak implementasi echoperintah yang berbeda yang tidak kompatibel satu sama lain. Oleh karena itu disarankan untuk menggunakan alat yang lebih standar printf. Lihat unix.stackexchange.com/questions/65803/… untuk tinjauan umum masalah yang lebih luas.
jimmij

Jawaban:


38

echo


Sebuah echoimplementasi yang ketat sesuai dengan Single Unix Specification akan menambahkan baris baru jika Anda lakukan:

echo 'line1\nline2'

Tapi itu bukan perilaku yang bisa diandalkan. Sebenarnya, sebenarnya tidak ada perilaku standar yang dapat Anda harapkan echo.

Operan

string

String yang akan ditulis ke output standar. Jika operan pertama adalah -n, atau jika salah satu operan berisi karakter < \backslash> , hasilnya ditentukan-implementasi .

Pada sistem konforman XSI , jika operan pertama -n, itu harus diperlakukan sebagai string, bukan opsi . Urutan karakter berikut harus diakui pada sistem yang sesuai dengan XSI dalam salah satu argumen:

\a- Tulis <alert> .

\b- Tulis <backspasi> .

\c- Menekan <newline> yang jika tidak mengikuti argumen terakhir di output. Semua karakter yang mengikuti \cargumen akan diabaikan.

\f- Tulis <form-feed> .

\n- Tulis <newline> .

\r- Tulis <carriage-return> .

\t- Tulis <tab> .

\v- Tuliskan <vertical-tab> .

\\- Tulis karakter <backslash> .

\0num- Tulis nilai 8-bit yang merupakan angka oktal nol, satu, dua, atau tiga digit num.

Jadi sebenarnya tidak ada cara umum untuk mengetahui cara menulis baris baru echo, kecuali bahwa Anda biasanya dapat mengandalkan melakukannya echo.

Sebuah bashshell biasanya tidak tidak sesuai dengan spesifikasi, dan menangani -ndan pilihan lain, tapi bahkan yang tidak pasti. Anda dapat melakukan:

shopt -s xpg_echo
echo hey\\nthere

hey
there

Dan bahkan itu tidak perlu jika bashtelah dibangun dengan opsi waktu bangun ...

--enable-xpg-echo-default

Jadikan echobawaan mengembangkan karakter backslash-escaped secara default, tanpa memerlukan -eopsi. Ini menetapkan nilai default dari xpg_echoopsi shell on, yang membuat Bash echoberperilaku lebih seperti versi yang ditentukan dalam Spesifikasi Unix Tunggal, versi 3. Lihat Bash Builtins , untuk deskripsi tentang urutan melarikan diri yang echomengenali.


printf


Di sisi lain, printfperilaku cukup jinak dibandingkan.

ALASAN

The printfutilitas ditambahkan untuk menyediakan fungsionalitas yang secara historis telah disediakan oleh echo. Namun, karena perbedaan yang tak dapat didamaikan dalam berbagai versi yang echomasih ada, versi ini memiliki beberapa fitur khusus, meninggalkan mereka ke printfutilitas baru ini , yang didasarkan pada satu di sistem Edisi Kesembilan.

Bagian DIPERLUASKAN DESKRIPSI hampir sama persis dengan printf()fungsi dalam standar ISO C, meskipun dijelaskan dalam hal notasi format file dalam Notasi Format File XBD .

Ini menangani format string yang menggambarkan argumennya - yang bisa berupa banyak hal, tetapi untuk string cukup banyak baik %bstring yte atau %string literal . Selain dari %formats di argumen pertama, itu berperilaku paling seperti %bargumen string yte, kecuali bahwa itu tidak menangani jalan \ckeluar.

printf ^%b%s$ '\n' '\n' '\t' '\t'

^
\n$^    \t$

Lihat Mengapa printflebih baik daripada echo? untuk lebih.


echo() printf


Anda dapat menulis sesuai standar Anda sendiri echoseperti ...

echo(){
    printf '%b ' "$@\n\c"
}

... yang seharusnya selalu melakukan hal yang benar secara otomatis.

Sebenarnya, tidak ... Itu mencetak literal \ndi bagian akhir argumen jika argumen terakhir berakhir dengan jumlah ganjil <backslashes> .

Tetapi ini tidak:

echo()
    case    ${IFS- } in
    (\ *)   printf  %b\\n "$*";;
    (*)     IFS=\ $IFS
            printf  %b\\n "$*"
            IFS=${IFS#?}
    esac

+1 untuk shopt -s xpg_echoopsi dalam echountuk digunakan -esecara default.
Vignesh Raja

Solusi ini tidak berfungsi tanpa -e. Saya terkejut bahwa tidak ada yang memperhatikan bahwa kecuali mungkin @HaydeSchiff
ha9u63ar

@ ha9u63ar - uhh ... apakah Anda membaca ini?
mikeserv

27

Lewati tanda -e ke echo untuk mengurai karakter yang lolos seperti "\ r \ n", seperti:

echo -e "Line 1\r\nLine2" >> readme.txt

Opsi "-e" sederhana yang bagus untuk membuat urutan pelarian berfungsi - ia mengatakan pada jawaban lain yang echotidak dapat diandalkan dan tidak mengikuti standar yang tidak sama printf.
Edward

1
Pastikan skrip Anda tidak mengandung literal \ r \ n, seperti dalam sebuah tr -d "\n"perintah.
Noumenon

8

Di semua versi bash yang saya gunakan, Anda bisa memasukkan baris baru literal ke string baik secara interaktif maupun dalam skrip, asalkan string tersebut cukup dikutip.

Secara interaktif:

$ echo "Line one
> Line two"
Line one
Line two
$

Dalam naskah:

echo "Line one
Line two"

4
echo -e "Line 1\r\nLine2" >> readme.txt

kemungkinan penggunaan lebih lanjut:

man echo

2

Orang-orang sudah menjawab dengan cukup, tetapi saya menolak untuk menerima dunia di mana gema menerima pilihan selain -n.

nl='
'
echo Line 1"$nl"Line 2"$nl"Line 3

1

Jika Anda memiliki karakter yang bukan bagian dari pesan, Anda dapat menyalurkan melalui sed

$ echo "Time on the next line:@$(date +"%Y-%m-%dT%T%z")" | sed -e's/@/\n/g'
Time on the next line:
2016-03-25T10:12:39-0500
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.