Mengapa bash menghapus \ n dalam $ (file cat)?

24

Jika saya memiliki file yang input.txtberisi:

hello
world
!

Kemudian mengeksekusi perintah bash echo $(cat input.txt)akan menampilkan ini:

hello world !

Mengapa dan bagaimana saya bisa memperbaikinya untuk menampilkan dengan tepat apa yang ada di dalam file bagaimana di dalam file?

f.ardelian
sumber

Jawaban:

32

Jika Anda menggunakan

echo "$(cat input.txt)"

itu akan bekerja dengan benar.

Mungkin input gema dipisahkan oleh baris baru, dan itu akan menanganinya sebagai perintah terpisah, sehingga hasilnya akan tanpa baris baru.

arian
sumber
Bagus! Jadi apa bedanya (jika ada) antara $ () dan backticks? (Maaf jika ini terlalu tangensial)
Chan-Ho Suh
Mereka setara, kecuali kenyataan bahwa $ (...) lebih mudah untuk bersarang. Dalam kedua kasus, jika Anda tidak mengutip hasilnya, itu akan diubah menjadi beberapa argumen di ruang putih.
James Henstridge
3
Tetapi karakter baris baru terakhir dihilangkan, bahkan dalam tanda kutip ganda. Sebaliknya, operator backtick Perl memperluas ke seluruh output dari perintah, termasuk semua baris baru.
Keith Thompson
6
@KeithThompson ya, substitusi perintah menghapus semua baris baru dari output. Itu memiliki keuntungan misalnya, echo "$(date) something"menghilangkan garis baru yang tertinggal dari keluaran tanggal, membuat gema itu mengeluarkan tanggal dan "sesuatu" pada baris yang sama. Jika Anda perlu menyimpan file atau output perintah "apa adanya", gunakan mapfile ( help mapfile), read -rd ''atau read-loop while.
geirha
Terima kasih semuanya :-) Saya belajar sesuatu dari setiap komentar di sini!
Chan-Ho Suh
2

Dikutip dari halaman manual bash, bagian Command Substitution:

Baris baru yang disematkan tidak dihapus, tetapi mereka dapat dihapus selama pemisahan kata.

Sedikit lebih jauh, bagian yang sama:

Jika substitusi muncul dalam tanda kutip ganda, pemisahan kata dan perluasan pathname tidak dilakukan pada hasilnya.

Itu sebabnya echo "$(cat /etc/passwd)" berhasil.

Selain itu, orang harus sadar, bahwa penggantian perintah dengan spesifikasi POSIX menghilangkan baris baru:

$ echo "$(printf "one\ntwo\n\n\n")"
one
two

Dengan demikian, mengeluarkan file melalui $(cat file.txt)dapat menyebabkan hilangnya baris baru, dan itu bisa menjadi masalah jika integritas file keseluruhan adalah prioritas.

Sergiy Kolodyazhnyy
sumber
2

Anda dapat mempertahankan baris baru, misalnya dengan mengatur IFS untuk dikosongkan:

$ IFS=
$ a=$(cat links.txt)
$ echo "$a"
link1
link2
link3
Sarnath Jegadeesan
sumber