Bash 续行
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/7316107/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Bash continuation lines
提问by Ray Toal
How do you use bash continuation lines?
你如何使用 bash 续行?
I realize that you can do this:
我意识到你可以这样做:
echo "continuation \
lines"
>continuation lines
However, if you have indented code, it doesn't work out so well:
但是,如果您缩进了代码,则效果不佳:
echo "continuation \
lines"
>continuation lines
回答by Ray Toal
This is what you may want
这就是你可能想要的
$ echo "continuation"\
> "lines"
continuation lines
If this creates two arguments to echo and you only want one, then let's look at string concatenation. In bash, placing two strings next to each other concatenate:
如果这为 echo 创建了两个参数而您只想要一个,那么让我们看看字符串连接。在 bash 中,将两个相邻的字符串连接起来:
$ echo "continuation""lines"
continuationlines
So a continuation line without an indentis one way to break up a string:
因此,没有缩进的续行是拆分字符串的一种方式:
$ echo "continuation"\
> "lines"
continuationlines
But when an indent is used:
但是当使用缩进时:
$ echo "continuation"\
> "lines"
continuation lines
You get two arguments because this is no longer a concatenation.
你得到两个参数,因为这不再是一个串联。
If you would like a single string which crosses lines, while indenting but not getting all those spaces, one approach you can try is to ditch the continuation line and use variables:
如果您想要一个跨行的字符串,同时缩进但没有获得所有这些空格,您可以尝试的一种方法是放弃续行并使用变量:
$ a="continuation"
$ b="lines"
$ echo $a$b
continuationlines
This will allow you to have cleanly indented code at the expense of additional variables. If you make the variables local it should not be too bad.
这将允许您以额外的变量为代价获得干净的缩进代码。如果您将变量设为本地,应该不会太糟糕。
回答by tripleee
Here documents with the <<-HERE
terminator work well for indented multi-line text strings. It will remove any leading tabs from the here document. (Line terminators will still remain, though.)
此处带有<<-HERE
终止符的文档适用于缩进的多行文本字符串。它将从此处的文档中删除所有前导选项卡。(不过,行终止符仍将保留。)
cat <<-____HERE
continuation
lines
____HERE
See also http://ss64.com/bash/syntax-here.html
另见http://ss64.com/bash/syntax-here.html
If you need to preserve some, but not all, leading whitespace, you might use something like
如果您需要保留一些(但不是全部)前导空格,您可以使用类似
sed 's/^ //' <<____HERE
This has four leading spaces.
Two of them will be removed by sed.
____HERE
or maybe use tr
to get rid of newlines:
或者可能用于tr
摆脱换行符:
tr -d '2' <<-____
continuation
lines
____
(The second line has a tab and a space up front; the tab will be removed by the dash operator before the heredoc terminator, whereas the space will be preserved.)
(第二行前面有一个制表符和一个空格;制表符将在heredoc 终止符之前被破折号运算符删除,而空格将被保留。)
For wrapping long complex strings over many lines, I like printf
:
为了将复杂的长字符串包装在多行上,我喜欢printf
:
printf '%s' \
"This will all be printed on a " \
"single line (because the format string " \
"doesn't specify any newline)"
It also works well in contexts where you want to embed nontrivial pieces of shell script in another language where the host language's syntax won't let you use a here document, such as in a Makefile
or Dockerfile
.
在您想以另一种语言嵌入重要的 shell 脚本片段的上下文中,它也能很好地工作,而宿主语言的语法不允许您使用 here 文档,例如在 aMakefile
或Dockerfile
.
printf '%s\n' >./myscript \
'#!/bin/sh` \
"echo \"G'day, World\"" \
'date +%F\ %T' && \
chmod a+x ./myscript && \
./myscript
回答by tworec
You can use bash arrays
您可以使用bash 数组
$ str_array=("continuation"
"lines")
then
然后
$ echo "${str_array[*]}"
continuation lines
there is an extra space, because (after bash manual):
有一个额外的空间,因为(在 bash 手册之后):
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
如果单词是双引号,则
${name[*]}
扩展为单个单词,每个数组成员的值由 IFS 变量的第一个字符分隔
So set IFS=''
to get rid of extra space
所以设置IFS=''
摆脱额外的空间
$ IFS=''
$ echo "${str_array[*]}"
continuationlines
回答by Cybernaut
In certain scenarios utilizing Bash's concatenation ability might be appropriate.
在某些情况下,利用 Bash 的连接能力可能是合适的。
Example:
例子:
temp='this string is very long '
temp+='so I will separate it onto multiple lines'
echo $temp
this string is very long so I will separate it onto multiple lines
From the PARAMETERS section of the Bash Man page:
从 Bash 手册页的参数部分:
name=[value]...
...In the context where an assignment statement is assigning a value to a shell variable or array index, the += operator can be used to append to or add to the variable's previous value. When += is applied to a variable for which the integer attribute has been set, value is evaluated as an arithmetic expression and added to the variable's current value, which is also evaluated. When += is applied to an array variable using compound assignment (see Arrays below), the variable's value is not unset (as it is when using =), and new values are appended to the array beginning at one greater than the array's maximum index (for indexed arrays) or added as additional key-value pairs in an associative array. When applied to a string-valued variable, value is expanded and appended to the variable's value.
名称=[值]...
...在赋值语句为 shell 变量或数组索引赋值的上下文中,+= 运算符可用于附加或添加到变量的先前值。当 += 应用于已设置 integer 属性的变量时, value 将作为算术表达式计算并添加到变量的当前值,该值也被计算。当使用复合赋值将 += 应用于数组变量时(请参阅下面的数组),变量的值不会被取消设置(就像使用 = 时一样),并且新值会从大于数组最大索引的 1 开始追加到数组(对于索引数组)或作为关联数组中的附加键值对添加。 当应用于字符串值变量时,值被扩展并附加到变量的值。
回答by haridsv
I came across a situation in which I had to send a long message as part of a command argument and had to adhere to the line length limitation. The commands looks something like this:
我遇到了一种情况,我必须将长消息作为命令参数的一部分发送,并且必须遵守行长度限制。命令看起来像这样:
somecommand --message="I am a long message" args
The way I solved this is to move the message out as a here document (like @tripleee suggested). But a here document becomes a stdin, so it needs to be read back in, I went with the below approach:
我解决这个问题的方法是将消息作为此处的文档移出(如@tripleee 建议的那样)。但是这里的文档变成了标准输入,所以需要重新读入,我采用了以下方法:
message=$(
tr "\n" " " <<- END
This is a
long message
END
)
somecommand --message="$message" args
This has the advantage that $message
can be used exactly as the string constant with no extra whitespace or line breaks.
这具有$message
可以完全用作字符串常量的优点,没有额外的空格或换行符。
Note that the actual message lines above are prefixed with a tab
character each, which is stripped by here document itself (because of the use of <<-
). There are still line breaks at the end, which are then replaced by dd
with spaces.
请注意,上面的实际消息行tab
每行都以一个字符为前缀,该字符被此处的文档本身剥离(因为使用了<<-
)。最后仍然有换行符,然后dd
用空格替换。
Note also that if you don't remove newlines, they will appear as is when "$message"
is expanded. In some cases, you may be able to workaround by removing the double-quotes around $message
, but the message will no longer be a single argument.
另请注意,如果您不删除换行符,它们将在"$message"
展开时按原样显示。在某些情况下,您可以通过删除 周围的双引号来解决$message
,但消息将不再是单个参数。
回答by rjni
You could simply separate it with newlines (without using backslash) as required within the indentation as follows and just strip of new lines.
您可以根据需要在缩进中使用换行符(不使用反斜杠)简单地将其分开,如下所示,并仅去除新行。
Example:
例子:
echo "continuation
of
lines" | tr '\n' ' '
Or if it is a variable definition newlines gets automatically converted to spaces. So, strip of extra spaces only if applicable.
或者如果它是一个变量定义换行符会自动转换为空格。因此,仅在适用时去除额外的空格。
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
回答by Jon McClung
This isn't exactly what the user asked, but another way to create a long string that spans multiple lines is by incrementally building it up, like so:
这并不是用户所要求的,但另一种创建跨越多行的长字符串的方法是逐步构建它,如下所示:
$ greeting="Hello"
$ greeting="$greeting, World"
$ echo $greeting
Hello, World
Obviously in this case it would have been simpler to build it one go, but this style can be very lightweight and understandable when dealing with longer strings.
显然,在这种情况下,一次性构建它会更简单,但是在处理更长的字符串时,这种样式非常轻巧且易于理解。
回答by ingyhere
Line continuations also can be achieved through clever use of syntax.
行延续也可以通过巧妙地使用语法来实现。
In the case of echo
:
在以下情况下echo
:
# echo '-n' flag prevents trailing <CR>
echo -n "This is my one-line statement" ;
echo -n " that I would like to make."
This is my one-line statement that I would like to make.
In the case of vars:
在 var 的情况下:
outp="This is my one-line statement" ;
outp+=" that I would like to make." ;
echo -n "${outp}"
This is my one-line statement that I would like to make.
Another approach in the case of vars:
vars 的另一种方法:
outp="This is my one-line statement" ;
outp="${outp} that I would like to make." ;
echo -n "${outp}"
This is my one-line statement that I would like to make.
Voila!
瞧!
回答by Paul Hodges
Depending on what sort of risks you will accept and how well you know and trust the data, you can use simplistic variable interpolation.
根据您将接受的风险类型以及您对数据的了解和信任程度,您可以使用简单的变量插值。
$: x="
this
is
variably indented
stuff
"
$: echo "$x" # preserves the newlines and spacing
this
is
variably indented
stuff
$: echo $x # no quotes, stacks it "neatly" with minimal spacing
this is variably indented stuff
回答by mMontu
However, if you have indented code, it doesn't work out so well:
echo "continuation \ lines" >continuation lines
但是,如果您缩进了代码,则效果不佳:
echo "continuation \ lines" >continuation lines
Try with single quotes and concatenating the strings:
尝试使用单引号并连接字符串:
echo 'continuation' \
'lines'
>continuation lines
Note: the concatenation includes a whitespace.
注意:连接包含一个空格。