2011-09-06 36 views
109

Làm thế nào để bạn sử dụng các đường liên tục bash?Đường liên tục Bash

Tôi nhận ra rằng bạn có thể làm điều này:

echo "continuation \ 
lines" 
>continuation lines 

Tuy nhiên, nếu bạn đã thụt mã, nó không hoạt động ra rất tốt:

echo "continuation \ 
    lines" 
>continuation  lines 
+4

Hướng dẫn về kiểu vỏ Bash của Google [khuyến nghị "ở đây" tài liệu] (https://google.github.io/styleguide/shell.xml # Line_Length_and_Long_Strings) cho "Nếu bạn phải viết các chuỗi dài hơn 80 ký tự". Xem [@ tripleee's answer] (http://stackoverflow.com/questions/7316107/bash-continuation-lines/7316685#7316685). –

Trả lời

113

Đây là những gì bạn có thể muốn

$  echo "continuation"\ 
>  "lines" 
continuation lines 

Nếu điều này tạo ra hai đối số để echo và bạn chỉ muốn một đối số, thì hãy xem chuỗi nối. Trong bash, đặt hai chuỗi bên cạnh mỗi concatenate khác:

$ echo "continuation""lines" 
continuationlines 

Vì vậy, một dòng tiếp nối mà không có một thụt là một cách để chia tay một chuỗi:

$ echo "continuation"\ 
> "lines" 
continuationlines 

Nhưng khi một indent được sử dụng :

$  echo "continuation"\ 
>  "lines" 
continuation lines 

Bạn nhận được hai đối số vì không còn nối nữa.

Nếu bạn muốn một chuỗi duy nhất mà đi qua đường, trong khi thụt nhưng không nhận được tất cả những không gian, một cách tiếp cận bạn có thể thử là để mương tiếp tục dòng và sử dụng biến:

$ a="continuation" 
$ b="lines" 
$ echo $a$b 
continuationlines 

này sẽ cho phép bạn để có mã thụt lề rõ ràng với chi phí của các biến bổ sung. Nếu bạn tạo các biến cục bộ, nó không nên quá tệ.

+0

Cảm ơn sự giúp đỡ của bạn, nhưng trong khi điều này loại bỏ không gian, chúng bây giờ là các tham số riêng biệt (Bash giải thích các khoảng trống trên dòng thứ hai là dấu tách tham số) và bây giờ chỉ được in chính xác vì lệnh echo. –

+1

Ồ, bạn muốn có một chuỗi (bash) duy nhất để mở rộng dòng! Tôi hiểu rồi. –

+3

Giải pháp với một biến: 's =" chuỗi số 1 " s + =" chuỗi số 2 " s + =" chuỗi số 3 " echo" $ s "' –

25

Tài liệu ở đây với trình kết thúc <<-HERE hoạt động tốt cho chuỗi văn bản nhiều dòng thụt lề. Nó sẽ xóa bất kỳ tab hàng đầu nào khỏi tài liệu ở đây.

cat <<-____HERE 
    continuation 
    lines 
____HERE 

Xem thêm http://ss64.com/bash/syntax-here.html

Nếu bạn cần phải duy trì một số người, nhưng không phải tất cả, khoảng trắng hàng đầu, bạn có thể sử dụng một cái gì đó llke

sed 's/^ //' <<____HERE 
    This has four leading spaces. 
    Two of them will be removed by sed. 
____HERE 
-1

Điều này có lẽ không thực sự trả lời câu hỏi của bạn nhưng bạn có thể thấy nó hữu ích.

Lệnh đầu tiên tạo tập lệnh được hiển thị bởi lệnh thứ hai.

Lệnh thứ ba làm cho tập lệnh đó thực thi được.

Lệnh thứ tư cung cấp ví dụ sử dụng.

[email protected]:~/tmp/so$ echo $'#!/usr/bin/env python\nimport textwrap, sys\n\ndef bash_dedent(text):\n """Dedent all but the first line in the passed `text`."""\n try:\n  first, rest = text.split("\\n", 1)\n  return "\\n".join([first, textwrap.dedent(rest)])\n except ValueError:\n  return text # single-line string\n\nprint bash_dedent(sys.argv[1])' > bash_dedent 
[email protected]:~/tmp/so$ cat bash_dedent 
#!/usr/bin/env python 
import textwrap, sys 

def bash_dedent(text): 
    """Dedent all but the first line in the passed `text`.""" 
    try: 
     first, rest = text.split("\n", 1) 
     return "\n".join([first, textwrap.dedent(rest)]) 
    except ValueError: 
     return text # single-line string 

print bash_dedent(sys.argv[1]) 
[email protected]:~/tmp/so$ chmod a+x bash_dedent 
[email protected]:~/tmp/so$ echo "$(./bash_dedent "first line 
>  second line 
>  third line")" 
first line 
second line 
third line 

Lưu ý rằng nếu bạn thực sự muốn sử dụng kịch bản này, nó có ý nghĩa hơn để di chuyển tập lệnh thực thi vào ~/bin để nó sẽ nằm trong đường dẫn của bạn.

Kiểm tra tham chiếu python để biết chi tiết về cách hoạt động của textwrap.dedent.

Nếu việc sử dụng $'...' hoặc "$(...)" gây nhầm lẫn cho bạn, hãy đặt một câu hỏi khác (mỗi cấu trúc) nếu chưa có câu hỏi. Nó có thể là tốt đẹp để cung cấp một liên kết đến câu hỏi bạn tìm/yêu cầu để những người khác sẽ có một tài liệu tham khảo liên kết.

+5

Có chủ ý và thậm chí hữu ích- Mặc dù điều này có thể là, OP yêu cầu lời khuyên về cú pháp bash cơ bản, và bạn đã cho anh ta một định nghĩa hàm python sử dụng các mô hình OO, kiểm soát lưu lượng đặc biệt và nhập khẩu. Hơn nữa, bạn gọi là thực thi như là một phần của một nội suy chuỗi - một cái gì đó mà một người hỏi loại câu hỏi này chắc chắn sẽ không thấy trong bash. –

2

Tôi tình cờ gặp một tình huống trong đó tôi phải gửi một tin nhắn dài như là một phần của một đối số lệnh và phải tuân theo giới hạn độ dài của dòng. Các lệnh trông giống như sau:

somecommand --message="I am a long message" args 

Cách tôi giải quyết điều này là di chuyển thư ra dưới dạng tài liệu tại đây (như @tripleee được đề xuất). Nhưng một tài liệu ở đây sẽ trở thành một thiết bị nhập chuẩn, vì vậy nó cần phải được đọc lại, tôi đã đi với cách tiếp cận dưới đây:

message=$(
    tr "\n" " " <<- END 
     This is a 
     long message 
END 
) 
somecommand --message="$message" args 

này có ưu điểm là $message thể được sử dụng chính xác như chuỗi liên tục không có khoảng trắng thêm hoặc ngắt dòng.

Lưu ý rằng các dòng thư thực tế ở trên được bắt đầu bằng một ký tự tab, mỗi ký tự bị tước bởi chính tài liệu này (vì việc sử dụng <<-). Vẫn còn ngắt dòng ở cuối, sau đó được thay thế bằng dd bằng dấu cách.

Cũng lưu ý rằng nếu bạn không xóa các dòng mới, chúng sẽ xuất hiện như khi "$message" được mở rộng. Trong một số trường hợp, bạn có thể giải quyết sự cố bằng cách xóa dấu ngoặc kép xung quanh $message, nhưng thư sẽ không còn là một đối số.

-1

However, if you have indented code, it doesn't work out so well:

echo "continuation \ 
    lines" 
>continuation  lines 

Hãy thử với dấu nháy đơn và concatenating các dây:

echo 'continuation' \ 
    'lines' 
>continuation lines 

Lưu ý: nối bao gồm một khoảng trắng.

+1

Nó hoạt động với các đối số dạng chuỗi và chuỗi, nhưng nó không hoạt động với các thứ khác, như gán biến. Mặc dù câu hỏi không phải là về các biến, sử dụng echo chỉ là một ví dụ. Thay vì 'echo' nếu bạn có 'x =', bạn sẽ gặp lỗi: 'lines: command not found'. –

2

Bạn có thể sử dụng bash arrays

$ str_array=("continuation" 
      "lines") 

sau đó

$ echo "${str_array[*]}" 
continuation lines 

có một không gian thêm, bởi vì (sau khi bash thủ công):

If the word is double-quoted, ${name[*]} expands to a single word with the value of each array member separated by the first character of the IFS variable

Vì vậy, thiết IFS='' để thoát khỏi không gian thêm

$ IFS='' 
$ echo "${str_array[*]}" 
continuationlines 
0

Bạn có thể chỉ cần tách nó bằng dòng mới (không sử dụng dấu gạch chéo ngược) theo yêu cầu trong thụt đầu dòng như sau và chỉ dải các dòng mới.

Ví dụ:

echo "continuation 
of 
lines" | tr '\n' ' ' 

Hoặc nếu nó là một dòng mới định nghĩa biến được tự động chuyển đổi sang không gian. Vì vậy, dải không gian thêm chỉ khi áp dụng.

x="continuation 
of multiple 
lines" 
y="red|blue| 
green|yellow" 

echo $x # This will do as the converted space actually is meaningful 
echo $y | tr -d ' ' # Stripping of space may be preferable in this case 
Các vấn đề liên quan