如何在缩进的情况下将字符串值分配给多行变量?

如何在缩进的情况下将字符串值分配给多行变量?

问题:

  1. 我需要为一个变量分配一个相当长的值。
  2. 我的脚本的所有行都必须位于一定数量的列下。

因此,我尝试使用多行来分配它。

没有缩进很简单:

VAR="This displays without \
any issues."
echo "${VAR}"

结果:

This displays without any issues.

然而,带有缩进:

    VAR="This displays with \
    extra spaces."
    echo "${VAR}"

结果:

This displays with      extra spaces.

如果没有这些空间,我该如何优雅地分配它?

答案1

这里的问题是你用双引号(“”)包围变量。删除它,一切都会正常进行。

    VAR="This displays with \
    extra spaces."
    echo ${VAR}

输出

 This displays with extra spaces.

这里的问题是双引号变量保留所有空白字符。如果您明确需要它,可以使用它。

例如,

$ echo "Hello     World    ........ ...            ...."

将打印

Hello     World    ........ ...            ....

删除引号后,情况有所不同

$ echo Hello     World    ........ ...            ....
Hello World ........ ... ....

这里,Bash 删除了文本中的额外空格,因为在第一种情况下,整个文本被视为“单个”参数,从而保留了额外的空格。但在第二种情况下,echo命令接收文本作为 5 个参数。

在将参数传递给命令时引用变量也很有帮助。

在下面的命令中,echo仅获取单个参数"Hello World"

$ variable="Hello World"
$ echo "$variable"

但在下面的情况下,echo有两个参数为HelloWorld

$ variable="Hello World"
$ echo $variable

答案2

给出的解决方案厄索须米凯尔·布卡斯是执行此操作的常见且更便携的方法。

这里有一些bash解决方案(其中一些也应该适用于其他 shell,例如zsh)。首先使用+=追加运算符(对于整型变量、常规变量和数组,其工作方式略有不同)。

text="Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod "
text+="tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, "
text+="quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea ..." 

如果您想在文本中使用换行符(或其他空格/转义符),请使用$''引号:

text=$'Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod\n'
text+=$'...'

接下来,使用将printf -v格式化值分配给变量

printf -v text "%s" "Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed " \
                    "do eiusmod empor incididunt ut labore et dolore magna aliqua. "\
                    "Ut enim ad minim veniam ..."

这里的技巧是参数多于格式说明符,因此与大多数printf函数不同,bash 会重复使用格式字符串,直到它用完为止。您可以\n在格式字符串中放置 a ,或使用 $'' (或两者)来处理空格。

接下来,使用数组:

text=("Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod "
      "tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, "
      "quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea ..." )

您还可以使用+=逐行构建文本(请注意()):

text+=("post script")

但在这里,如果您想一次性获得整个文本内容,则必须记住“展平”数组

echo "$text"      # only outputs index [0], the first line
echo "${text[*]}" # output complete text (joined by first character of IFS)

(整数索引数组是隐式排序的,与关联数组不同)这为您提供了更多的灵活性,因为您可以操作行,甚至切片和切丁如果需要的话。

最后,使用readorreadarray和“此处文档”:

read -r -d '' text <<-"EOT"
        Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod
        tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, 
        quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea ...
EOT

readarray -t textarray <<-"EOT"
        Lorem [...]
EOT  

此处文档形式<<-意味着所有前导硬制表符都将从输入中删除,因此您必须使用制表符来缩进文本。周围的引号"EOT"会阻止 shell 扩展功能,因此逐字使用输入。它read使用 NUL 字节分隔输入,因此它将一次性读取换行分隔文本。使用readarray(又名mapfile,自 bash-4.0 起可用)它读入一个数组,并-t在每行上删除换行符。

答案3

有一个特殊的heredoc语法可以删除选项卡在所有行的开头:“<<-”(注意添加的破折号)

http://tldp.org/LDP/abs/html/here-docs.html

例19-4。多行消息,制表符被抑制

你可以这样使用它:

v="$(cat <<-EOF
    A
        B
    C
EOF
)"
echo "$v"

结果 :

A
B
C

它仅适用于制表符,不适用于空格。

答案4

让 shell 吃掉不需要的换行符和以下空格:

$ cat weird.sh 
#!/bin/sh

        var1="A weird(?) $(
             )multi line $(
             )text idea. $(
             )PID=$$"

        var2='You can '$(
            )'avoid expansion '$(
            )'too: PID=$$'

        var3='Or mix it: '$(
            )'To insert the PID use $$. '$(
            )"It expands to e.g. $$."

        echo "$var1"
        echo "$var2"
        echo "$var3"
$ sh weird.sh 
A weird(?) multi line text idea. PID=13960
You can avoid expansion too: PID=$$
Or mix it: To insert the PID use $$. It expands to e.g. 13960.

所以这是可能的......但肯定喜欢或不喜欢这个解决方案是一个品味问题......

相关内容