用换行符在 bash 中构建一个字符串

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/19912681/
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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-18 08:35:27  来源:igfitidea点击:

Build a string in bash with newlines

bashshellnewline

提问by Palace Chan

I'm going through a script in bash where depending on the conditionals I want to append to a variable different things and then display it at the very end, something like this:

我正在 bash 中浏览一个脚本,其中根据我想附加到变量的不同内容的条件,然后在最后显示它,如下所示:

VAR="The "

if [[ whatever ]]; then
    VAR="$VAR cat wears a mask"
elif [[ whatevs ]]; then
    VAR="$VAR rat has a flask"
fi

but i run into difficulties if I try to use this form of building up VAR by appending to it when I want to occasionally append newlines into it. How would I do VAR="$VAR\nin a box", for example? I have seen usage of $'\n'before but not when also trying to use $VARbecause of the appending.

但是,如果我想偶尔在其中添加换行符时,尝试通过附加到它来使用这种构建 VAR 的形式,我会遇到困难。VAR="$VAR\nin a box"例如,我该怎么做?我之前看到过使用,$'\n'$VAR由于附加而在尝试使用时没有看到。

回答by gniourf_gniourf

Using ANSI-C quoting:

使用ANSI-C 引用

var="$var"$'\n'"in a box"

You could put the $'\n'in a variable:

你可以把它$'\n'放在一个变量中:

newline=$'\n'
var="$var${newline}in a box"

By the way, in this case, it's better to use the concatenation operator:

顺便说一下,在这种情况下,最好使用连接运算符:

var+="${newline}in a box"

If you don't like ANSI-C quoting, you can use printfwith its -voption:

如果你不喜欢 ANSI-C 引用,你可以使用printf它的-v选项:

printf -v var '%s\n%s' "$var" "in a box"

Then, to print the content of the variable var, don't forget quotes!

然后,要打印变量的内容var,不要忘记引号!

echo "$var"

or, better yet,

或者,更好的是,

printf '%s\n' "$var"

Remark.Don't use upper case variable names in Bash. It's terrible, and one day it will clash with an already existing variable!

评论。不要在 Bash 中使用大写变量名。这太可怕了,总有一天它会与一个已经存在的变量发生冲突!



You could also make a function to append a newline and a string to a variable using indirect expansion (have a look in the Shell Parameter Expansionsection of the manual) as so:

您还可以创建一个函数,使用间接扩展(查看手册Shell 参数扩展部分)将换行符和字符串附加到变量如下所示:

append_with_newline() { printf -v "" '%s\n%s' "${!1}" ""; }

Then:

然后:

$ var="The "
$ var+="cat wears a mask"
$ append_with_newline var "in a box"
$ printf '%s\n' "$var"
The cat wears a mask
in a box
$ # there's no cheating, look at the content of var:
$ declare -p var
declare -- var="The cat wears a mask
in a box"


Just for fun, here's a generalized version of the append_with_newlinefunction that takes n+1arguments (n≥1) and that will concatenate them all (with exception of the first one being the name of a variable that will be expanded) using a newline as separator, and puts the answer in the variable, the name of which is given in the first argument:

只是为了好玩,这里有一个通用版本的append_with_newline函数,它接受n+1 个参数(n≥1)并使用换行符将它们全部连接起来(第一个是将被扩展的变量的名称除外)作为分隔符,并将答案放在变量中,变量的名称在第一个参数中给出:

concatenate_with_newlines() { local IFS=$'\n'; printf -v "" '%s\n%s' "${!1}" "${*:2}"; }

Look how well it works:

看看效果如何:

$ var="hello"
$ concatenate_with_newlines var "a gorilla" "a banana" "and foobar"
$ printf '%s\n' "$var"
hello
a gorilla
a banana
and foobar
$ # :)

It's a funny trickery with IFSand "$*".

这是一个有趣的权谋与IFS"$*"

回答by chepner

By default, bashdoes not process escape characters. The assignment

默认情况下,bash不处理转义字符。那作业

VAR="foo\nbar"

assigns 8 characters to the variable VAR: 'f', 'o', 'o', '\', 'n', 'b', 'a', and 'r'. The POSIX standard states that the echocommand should treat the two-character string \nin its arguments as a linefeed; bashdoes not follow the standard in this case and requires the -eoption to enable this processing. The printfcommand follows the POSIX specification and treats literal "\n" in its argument as a linefeed, but does not expand such uses in strings that replace placeholders: printf "%s\n" "$VAR"would still output

为变量分配 8 个字符VAR:'f'、'o'、'o'、'\'、'n'、'b'、'a' 和 'r'。POSIX 标准规定该echo命令应将\n其参数中的两个字符的字符串视为换行符;bash在这种情况下不遵循标准,并且需要-e启用此处理的选项。该printf命令遵循 POSIX 规范并将其参数中的文字“\n”视为换行符,但不会在替换占位符的字符串中扩展此类用途:printf "%s\n" "$VAR"仍会输出

foo\nbar

instead of

代替

foo
bar

To include an actual linefeed character in a string, you can use ANSI quoting:

要在字符串中包含实际的换行符,您可以使用 ANSI 引用:

VAR=$'foo\nbar'

which has the drawback that the string is otherwise processed as a single-quoted string, and cannot contain parameter expansions or command substitutions. Another option is that a string that spans multiple lines will contain the quoted linefeed characters:

它的缺点是字符串被处理为单引号字符串,并且不能包含参数扩展或命令替换。另一种选择是跨多行的字符串将包含带引号的换行符:

$ VAR="foo
> bar"
$ echo "$foo"
foo
bar

回答by anubhava

It works this way:

它是这样工作的:

> VAR=foo
> VAR="$VAR\nrat has a flask"
> echo -e "$VAR"
foo
rat has a flask