Tại sao bash xóa \ n trong $ (tệp cat)?


24

Nếu tôi có tệp input.txtchứa:

hello
world
!

Sau đó, thực hiện lệnh bash echo $(cat input.txt)sẽ xuất ra điều này:

hello world !

Tại sao và làm cách nào tôi có thể sửa nó để xuất chính xác những gì trong tệp như thế nào trong tệp?

Câu trả lời:


32

Nếu bạn dùng

echo "$(cat input.txt)"

Nó sẽ hoạt động chính xác.

Có lẽ đầu vào của echo được phân tách bằng các dòng mới và nó sẽ xử lý nó như các lệnh riêng biệt, vì vậy kết quả sẽ không có dòng mới.


Tốt đẹp! Vì vậy, sự khác biệt (nếu có) giữa $ () và backticks là gì? (Xin lỗi nếu điều này quá tiếp tuyến)
Chan-Ho Suh

Chúng tương đương nhau, ngoại trừ thực tế là $ (...) dễ làm tổ hơn. Trong cả hai trường hợp, nếu bạn không trích dẫn kết quả, nó sẽ được mã hóa thành nhiều đối số trên khoảng trắng.
James Henstridge

3
Nhưng ký tự dòng mới cuối cùng bị bỏ qua, ngay cả trong dấu ngoặc kép. Ngược lại, toán tử backtick của Perl mở rộng ra toàn bộ đầu ra của lệnh, bao gồm tất cả các dòng mới.
Keith Thompson

6
@KeithThndry có, thay thế lệnh sẽ loại bỏ tất cả các dòng mới ở đầu ra. Điều đó có lợi thế, ví dụ như echo "$(date) something"tước bỏ dòng mới ở đầu ra của ngày, làm cho tiếng vang đó phát ra ngày và "một cái gì đó" trên cùng một dòng. Nếu bạn cần lưu trữ một tệp hoặc lệnh đầu ra "nguyên trạng", hãy sử dụng mapfile ( help mapfile) read -rd ''hoặc vòng lặp đọc.
geirha

Cảm ơn mọi người :-) Tôi đã học được điều gì đó từ mỗi bình luận ở đây!
Chan-Ho Suh

2

Trích dẫn từ trang hướng dẫn bash, phần Command Substitution:

Dòng mới được nhúng không bị xóa, nhưng chúng có thể bị xóa trong quá trình tách từ.

Xa hơn một chút, cùng một phần:

Nếu sự thay thế xuất hiện trong dấu ngoặc kép, việc tách từ và mở rộng tên đường dẫn không được thực hiện trên kết quả.

Đó là lý do tại sao echo "$(cat /etc/passwd)" hoạt động.

Ngoài ra, người ta cần lưu ý rằng việc thay thế lệnh bằng thông số kỹ thuật POSIX sẽ loại bỏ các dòng mới:

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

Do đó, việc xuất một tệp qua $(cat file.txt)có thể dẫn đến mất dòng mới, và đó có thể là một vấn đề nếu toàn bộ tệp được ưu tiên.


2

Bạn có thể giữ các dòng mới, ví dụ bằng cách đặt IFS thành trống:

$ IFS=
$ a=$(cat links.txt)
$ echo "$a"
link1
link2
link3
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.