Câu trả lời:
echo -e ' \t '
sẽ lặp lại 'dòng mới không gian tab không gian' ( -e
có nghĩa là 'cho phép giải thích các dấu gạch chéo ngược'):
$ echo -e ' \t ' | hexdump -C
00000000 20 09 20 0a | . .|
echo -e
không hoạt động từ Makefiles?
echo -e
không phải là POSIX và make
các cuộc gọi /bin/sh
thường không phải là chương trình sử dụng sử dụng một cách tương tác và thường không được -e
thực hiện. Đối với tính di động, sử dụng printf '\t'
thay thế.
man
trang cho echo
lệnh không đề cập đến tùy chọn -e
. Tuy nhiên, tùy chọn này được chấp nhận.
Sử dụng printf
, không echo
.
Có nhiều phiên bản khác nhau của echo
lệnh. Có /bin/echo
(có thể có hoặc không phải là phiên bản GNU Coreutils, tùy thuộc vào hệ thống) và echo
lệnh được tích hợp vào hầu hết các shell. Các phiên bản khác nhau có các cách khác nhau (hoặc không có cách nào) để chỉ định hoặc vô hiệu hóa các lối thoát cho các ký tự điều khiển.
printf
mặt khác, có ít biến thể hơn nhiều. Nó có thể tồn tại như một lệnh, thông thường /bin/printf
, và nó được tích hợp vào một số shell (bash và zsh có nó, tcsh và ksh không), nhưng các phiên bản khác nhau tương tự nhau nhiều hơn so với các phiên bản khác nhau echo
. Và bạn không cần phải nhớ các tùy chọn dòng lệnh (với một vài ngoại lệ; GNU Coreutils printf chấp nhận --version
và --help
, bash printf tích hợp chấp nhận -v var
để lưu trữ đầu ra trong một biến).
Ví dụ của bạn:
res=' 'x # res = "\t\tx"
printf '%s\n' "[$res]"
Và bây giờ là lúc để tôi thừa nhận rằng nó echo
sẽ hoạt động tốt như ví dụ bạn đang hỏi về; bạn chỉ cần đặt dấu ngoặc kép xung quanh đối số:
echo "[$res]"
như kmkaplan đã viết (hai năm rưỡi trước, tôi mới nhận thấy!). Vấn đề với các lệnh ban đầu của bạn:
res=' 'x # res = "\t\tx"
echo '['$res']' # expect [\t\tx]
không với echo
; đó là cái vỏ thay thế cái tab bằng một khoảng trắng trước khi echo
nhìn thấy nó.
echo
tốt cho đầu ra đơn giản, như echo hello world
, nhưng bạn nên sử dụng printf
bất cứ khi nào bạn muốn làm một cái gì đó phức tạp hơn. Bạn có thể bắt echo
đầu làm việc, nhưng mã kết quả có thể bị lỗi khi bạn chạy nó với một echo
triển khai khác hoặc một trình bao khác.
Bạn cũng có thể thử:
echo Hello$'\t'world.
Từ trang bash man:
Các từ có dạng $ 'chuỗi' được xử lý đặc biệt. Từ này mở rộng thành chuỗi, với các ký tự thoát dấu gạch chéo ngược được thay thế theo quy định của tiêu chuẩn ANSI C.
Vì vậy, bạn có thể làm điều này:
echo $'hello\tworld'
Sử dụng đúng nguyên văn tổ hợp phím, ^V
( CTRL+V
, C-v
, bất cứ điều gì ).
Khi bạn nhập ^V
vào thiết bị đầu cuối (hoặc trong hầu hết các trình soạn thảo Unix), ký tự sau được lấy nguyên văn . Bạn có thể sử dụng điều này để nhập một ký tự tab theo nghĩa đen bên trong một chuỗi bạn đang lặp lại.
Một cái gì đó giống như các công việc sau đây:
echo "^V<tab>" # CTRL+V, TAB
Tài liệu Bash ( qv , "trích dẫn-chèn")
trích dẫn-insert (Cq, Cv) Thêm ký tự tiếp theo mà bạn nhập vào nguyên văn dòng. Đây là cách chèn các chuỗi khóa như Cq chẳng hạn.
lưu ý phụ: theo điều này, ALT+TAB
nên làm điều tương tự, nhưng tất cả chúng ta đều ràng buộc chuỗi đó với chuyển đổi cửa sổ để chúng ta không thể sử dụng nó
chèn thẻ (M-TAB) Chèn ký tự tab.
-
Lưu ý: bạn có thể sử dụng chiến lược này với tất cả các loại nhân vật khác thường. Giống như một chiếc xe ngựa trở về:
echo "^V^M" # CTRL+V, CTRL+M
Điều này là do lợi nhuận vận chuyển là ASCII 13 và M là chữ cái thứ 13 của bảng chữ cái, vì vậy khi bạn nhập ^M
, bạn sẽ nhận được ký tự ASCII thứ 13. Bạn có thể thấy nó hoạt động bằng cách sử dụng ls^M
, tại một dấu nhắc trống, nó sẽ chèn trở lại vận chuyển, khiến cho dấu nhắc hành động giống như bạn nhấn return. Khi các ký tự này thường được giải thích, nguyên văn sẽ giúp bạn có được ký tự chữ.
grep
để bắt các dòng có chứa các tab
ký tự.
Sử dụng echo để in các giá trị của các biến là một cạm bẫy Bash phổ biến. Liên kết tham khảo: