tra-loi-cau-hoi-phat-trien-web.com

Cách thêm dòng mới vào các biến trong tập lệnh bash

Khi tôi làm

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

Tôi nhận được \n in ra quá. Làm thế nào tôi có thể có dòng mới sau đó?

80
Jiew Meng

Trong bash bạn có thể sử dụng cú pháp

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

Dấu ngoặc đơn đứng trước dấu $ là một cú pháp mới cho phép chèn các chuỗi thoát trong chuỗi.

Ngoài ra printf dựng sẵn cho phép lưu kết quả đầu ra vào một biến

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

Cả hai giải pháp không yêu cầu một subshell.

Nếu trong phần sau bạn cần in chuỗi, bạn nên sử dụng dấu ngoặc kép, như trong ví dụ sau:

echo "$str"

bởi vì khi bạn in chuỗi không có dấu ngoặc kép, dòng mới được chuyển thành khoảng trắng.

90
enzotib

Bạn có thể đặt các dòng mới theo nghĩa đen trong các trích dẫn đơn (trong bất kỳ Shell kiểu Bourne/POSIX nào).

str='Hello World
===========
'

Đối với chuỗi nhiều dòng, ở đây là tài liệ thường thuận tiện. Chuỗi được cung cấp như là đầu vào cho một lệnh.

mycommand <<'EOF'
Hello World
===========
EOF

Nếu bạn muốn lưu trữ chuỗi trong một biến, hãy sử dụng lệnh cat để thay thế lệnh. (Các) ký tự dòng mới ở cuối chuỗi sẽ bị tước bằng cách thay thế lệnh. Nếu bạn muốn giữ lại các dòng mới cuối cùng, hãy đặt một nút chặn ở cuối và loại bỏ nó sau đó. Trong các shell tương thích POSIX, bạn có thể viết str=$(cat <<'EOF'); str=${str%a} theo sau là heredoc thích hợp, nhưng bash yêu cầu heredoc xuất hiện trước dấu ngoặc đơn đóng.

str=$(cat <<'EOF'
Hello World
===========
a
EOF
); str=${str%a}

Trong ksh, bash và zsh, bạn có thể sử dụng biểu mẫu được trích dẫn $'…' Để mở rộng dấu gạch chéo ngược bên trong dấu ngoặc kép.

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

Bạn đang sử dụng "tiếng vang"? Hãy thử "echo -e".

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

Nếu bạn cần dòng mới trong tập lệnh của mình nhiều lần, bạn có thể khai báo một biến toàn cục đang giữ một dòng mới. Bằng cách đó, bạn có thể sử dụng nó trong chuỗi trích dẫn kép (mở rộng biến).

NL=$'\n'
str="Hello World${NL} and here is a variable $PATH ===========${NL}"
6
pihentagy

Để bổ sung cho các câu trả lời tuyệt vời hiện có:

Nếu bạn đang sử dụng bash và bạn thích sử dụng các dòng mới thực sự để dễ đọc, read là một tùy chọn khác cho capturing a here-doc in a, mà (giống như các giải pháp khác ở đây) không yêu cầu sử dụng một subshell.

# 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 Đảm bảo rằng read không diễn giải đầu vào (theo mặc định, nó sẽ xử lý dấu gạch chéo ngược đặc biệt, nhưng điều đó hiếm khi cần thiết).

  • -d '' Đặt dấu phân cách "bản ghi" thành một chuỗi trống, khiến read đọc toàn bộ đầu vào cùng một lúc (thay vì chỉ một dòng ).

Lưu ý rằng bằng cách để $IFS (Dấu tách trường bên trong) ở mặc định, $' \t\n' (Một khoảng trắng, tab, một dòng mới), bất kỳ khoảng trắng dẫn và theo dõi nào được cắt bớt từ giá trị được gán cho $str, bao gồm dòng mới ở đây.
[.__.] (Lưu ý rằng mặc dù phần thân của tài liệu ở đây bắt đầu trên dòng sau dấu phân cách bắt đầu ('EOF' Ở đây), nhưng nó lại không chứa một dòng mới hàng đầu ).

Thông thường, đây là hành vi mong muốn, nhưng nếu bạn muốn dòng mới đó, hãy sử dụng IFS= read -r -d '' Thay vì chỉ read -r -d '', Nhưng lưu ý rằng bất kỳ khoảng trắng hàng đầu và dấu sau đó được bảo tồn.
[.__.] (Lưu ý rằng việc trả trước IFS=  Trực tiếp cho lệnh read có nghĩa là việc chuyển nhượng chỉ có hiệu lực trong lệnh đó, do đó không cần khôi phục giá trị trước đó.)


Sử dụng tài liệu tại đây cũng cho phép bạn tùy ý sử dụng thụt lề để đặt chuỗi đa dòng cho dễ đọc:

# 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
===========]

Đặt - Giữa << Và dấu phân cách mở ở đây-doc ('EOF', Ở đây) làm cho các ký tự tab hàng đầu bị xóa khỏi thân tài liệu ở đây và thậm chí là dấu phân cách đóng, nhưng lưu ý rằng cái này chỉ hoạt động với các ký tự tab thực tế , không phải khoảng trắng, vì vậy nếu trình soạn thảo của bạn dịch phím nhấn vào không gian, thì cần thêm công việc .

3
mklement0

Từ tất cả các cuộc thảo luận, đây là cách đơn giản nhất đối với tôi:

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

Lệnh echo phải sử dụng dấu ngoặc kép.

3
kholis