7

我正在浏览 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="$VAR\nin a box"例如,我该怎么做?我已经看到了$'\n'之前的用法,但在尝试使用时却没有,$VAR因为附加了。

4

3 回答 3

10

使用ANSI-C 引用

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部分),如下所示:

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使用and是一个有趣的把戏"$*"

于 2013-11-11T17:57:12.247 回答
3

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

VAR="foo\nbar"

将 8 个字符分配给变量VAR:'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
于 2013-11-11T18:12:23.170 回答
1

它是这样工作的:

> VAR=foo
> VAR="$VAR\nrat has a flask"
> echo -e "$VAR"
foo
rat has a flask
于 2013-11-11T17:53:39.200 回答