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

时间:2013-11-11 17:50:52

标签: bash shell newline

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

VAR="The "

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

但是如果我想在偶尔添加换行符时尝试使用这种形式来建立VAR,我会遇到困难。例如,我如何做VAR="$VAR\nin a box"?我之前看到$'\n'的使用情况,但之后因为附加内容而尝试使用$VAR时却没有。

3 个答案:

答案 0 :(得分:5)

使用ANSI-C quoting

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

您可以将$'\n'放在变量中:

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

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

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

如果您不喜欢ANSI-C引用,则可以printf使用-v选项:

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

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

echo "$var"

或者,更好的是,

printf '%s\n' "$var"

备注。请勿在Bash中使用大写变量名称。这很可怕,有一天它会与现有的变量冲突!


您还可以创建一个函数,使用间接扩展将新行和字符串附加到变量(请查看Shell Parameter Expansion section of the manual),如下所示:

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

然后:

$ 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"

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

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

看看它有多好用:

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

使用IFS"$*"这是一个有趣的伎俩。

答案 1 :(得分:1)

它的工作原理如下:

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

答案 2 :(得分:1)

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

VAR="foo\nbar"

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

foo\nbar

而不是

foo
bar

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

VAR=$'foo\nbar'

,其缺点是字符串以其他方式处理为单引号字符串,并且不能包含参数扩展或命令替换。另一个选项是跨越多行的字符串将包含引用的换行符:

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