【问题标题】:Build a string in bash with newlines用换行符在 bash 中构建一个字符串
【发布时间】:2013-11-23 15:04:41
【问题描述】:

我正在浏览 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 时却没有。

【问题讨论】:

    标签: bash shell newline


    【解决方案1】:

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

    【讨论】:

      【解决方案2】:

      默认情况下,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
      

      【讨论】:

        【解决方案3】:

        它是这样工作的:

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

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2015-01-28
          • 2011-10-19
          • 2011-08-21
          • 2013-11-15
          • 2016-03-07
          • 1970-01-01
          • 2017-08-02
          • 2021-09-26
          相关资源
          最近更新 更多