我正在浏览一个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
时却没有。
答案 0 :(得分:5)
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