如何将我的长字符串常量分成多行?
我知道你可以这样做:
echo "continuation \
lines"
>continuation lines
但是,如果你有缩进的代码,它就不太好用了:
echo "continuation \
lines"
>continuation lines
如何将我的长字符串常量分成多行?
我知道你可以这样做:
echo "continuation \
lines"
>continuation lines
但是,如果你有缩进的代码,它就不太好用了:
echo "continuation \
lines"
>continuation lines
这可能是你想要的
$ echo "continuation"\
> "lines"
continuation lines
如果这会创建两个传递给echo的参数,而你只想要一个参数,那么我们可以考虑使用字符串拼接。在bash中,把两个字符串放在一起即可进行拼接:$ echo "continuation""lines"
continuationlines
没有缩进的续行是一种将字符串拆分的方法:
$ echo "continuation"\
> "lines"
continuationlines
但是当使用缩进时:$ echo "continuation"\
> "lines"
continuation lines
你得到了两个参数,因为这不再是连接操作。
如果你想要一个跨越多行的单独字符串,同时进行缩进但不想获得所有的空格,可以尝试放弃续行符并使用变量的方法:
$ a="continuation"
$ b="lines"
$ echo $a$b
continuationlines
这将允许您拥有清晰缩进的代码,但会增加额外的变量。如果将变量设为局部的话,应该不会有太多问题。
s="字符串1" s+="字符串2" s+=" 字符串3" echo "$s"
- Johnny Thunderman使用<<-HERE
终止符的Here文档可以很好地处理缩进的多行文本字符串。它将删除here文档中的所有前导制表符(但行终止符仍将保留)。
cat <<-____HERE
continuation
lines
____HERE
参见http://ss64.com/bash/syntax-here.html
如果您需要保留一些但不是全部的前导空格,可以使用类似以下的方法:
sed 's/^ //' <<____HERE
This has four leading spaces.
Two of them will be removed by sed.
____HERE
或者使用tr
命令来去掉换行符:
tr -d '\012' <<-____
continuation
lines
____
第二行开头有一个制表符和一个空格;在heredoc终止符之前,制表符将被破折号运算符删除,而空格将被保留。
对于需要跨越多行的长复杂字符串,我喜欢使用printf
:
printf '%s' \
"This will all be printed on a " \
"single line (because the format string " \
"doesn't specify any newline)"
它还可以在需要嵌入非平凡的 shell 脚本片段到另一种语言中的情况下发挥作用,在这种情况下,主机语言的语法不允许使用 Here 文档,例如在 Makefile
或 Dockerfile
中。
printf '%s\n' >./myscript \
'#!/bin/sh` \
"echo \"G'day, World\"" \
'date +%F\ %T' && \
chmod a+x ./myscript && \
./myscript
$ str_array=("continuation"
"lines")
然后
$ echo "${str_array[*]}"
continuation lines
由于bash手册上的解释,所以会有额外的空格:
如果单词被双引号括起来,
${name[*]}
将扩展为一个单词,其中每个数组成员的值由IFS变量的第一个字符分隔
因此,设置IFS=''
以消除额外的空格。
$ IFS=''
$ echo "${str_array[*]}"
continuationlines
"${str_array[@]}"
。 - tripleeeecho
来说没有关系,但对于其他情况可能会有很大的区别。https://dev59.com/M3A75IYBdhLWcg3wVniI - tworec在某些情况下,利用Bash的连接能力可能是合适的。
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
name=[value]...
当赋值语句将值分配给shell变量或数组索引时,在此上下文中,可以使用+=运算符来附加或添加到变量的先前值。当应用+=到已设置整数属性的变量时,value被评估为算术表达式,并添加到变量的当前值中,该值也被评估。当使用复合赋值(见下面的Arrays)应用于数组变量时,变量的值不会取消设置(如使用=时),并且新值将从一个最大索引比数组大1的位置(对于索引数组)开始附加,或作为关联数组中的额外键值对添加。当应用于字符串值变量时,value将被扩展并附加到变量的值。
echo "continuation
of
lines" | tr '\n' ' '
或者,如果它是一个变量定义,换行符会自动转换为空格。因此,仅在适用时去掉额外的空格。
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
我遇到了这样一种情况,需要将长消息作为命令参数发送,并且必须遵守行长度限制。命令看起来像这样:
somecommand --message="I am a long message" args
message=$(
tr "\n" " " <<-END
This is a
long message
END
)
somecommand --message="$message" args
这样做的好处是$message
可以像字符串常量一样使用,不会有额外的空格或换行符。
请注意,上面的实际消息行都以tab
字符为前缀,这是由于此处文档本身(因为使用了<<-
)而被剥离掉。仍然存在换行符,在使用tr
替换为空格时会被替换。
还要注意,如果您不删除换行符,则它们将在展开"$message"
时按原样显示。在某些情况下,您可以通过删除$message
周围的双引号来解决问题,但是该消息将不再是单个参数。
通过巧妙的语法使用,也可以实现行连接。
在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.
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.
在处理变量时,另一种方法是:
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.
看,完成了!
echo -n
的示例。 - tripleeeprintf
本身有相当大的可移植性问题。在2021年,抱怨echo
中删除尾随<CR>的-n
标志是一件非常微不足道的事情。我甚至会认为它提供了更多的控制,而不是吐出任何行结束符。个人而言,我更喜欢使用echo -ne "${outp}"
,它可以强制解释转义字符。建议严格遵循几十年的兼容性,使用带有HEREDOC的cat
。但实际上,原始发布者正在询问如何使用echo
,并且该问题已标记为Bash
。 - ingyhere这并不完全是用户要求的,但是另一种创建跨越多行的长字符串的方法是逐步构建它,像这样:
$ greeting="Hello"
$ greeting="$greeting, World"
$ echo $greeting
Hello, World
在 @tripleee 的 printf
示例基础上(+1):
LONG_STRING=$( printf '%s' \
'This is the string that never ends.' \
' Yes, it goes on and on, my friends.' \
' My brother started typing it not knowing what it was;' \
" and he'll continue typing it forever just because..." \
' (REPEAT)' )
echo $LONG_STRING
This is the string that never ends. Yes, it goes on and on, my friends. My brother started typing it not knowing what it was; and he'll continue typing it forever just because... (REPEAT)
我们已经在句子之间加入了明确的空格,例如 "' Yes
..."。另外,如果不需要这个变量:
echo "$( printf '%s' \
'This is the string that never ends.' \
' Yes, it goes on and on, my friends.' \
' My brother started typing it not knowing what it was;' \
" and he'll continue typing it forever just because..." \
' (REPEAT)' )"
This is the string that never ends. Yes, it goes on and on, my friends. My brother started typing it not knowing what it was; and he'll continue typing it forever just because... (REPEAT)
(注:该链接为英文维基百科,需要自行翻译)根据您愿意接受的风险以及了解和信任数据的程度,您可以使用简单的变量插值。
$: 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
MY_VAR = $(echo x $)
,然后你就得到了它。在我看来,这是保持我的代码可读性最好、最简单的答案,每行都是一个变量,保存着一个字符串本身。我需要导出这个值,但你不能导出数组。 - DKebler