我有这个多行字符串(包括引号):

abc'asdf"
$(dont-execute-this)
foo"bar"''

我将如何分配它到一个变量使用heredoc在Bash?

我需要保留换行符。

我不想转义字符串中的字符,这将是恼人的…


当前回答

数组是一个变量,所以在这种情况下mapfile可以工作

mapfile y <<'z'
abc'asdf"
$(dont-execute-this)
foo"bar"''
z

然后你可以像这样打印

printf %s "${y[@]}"

其他回答

真不敢相信我是第一个发这个的人。

@Erman和@Zombo很接近,但mapfile不只是读取数组…

考虑一下:

#!/bin/bash
mapfile -d '' EXAMPLE << 'EOF'
Hello
こんにちは
今晩は
小夜なら
EOF
echo -n "$EXAMPLE"

收益率:

Hello
こんにちは
今晩は
小夜なら

$ "是给mapfile的分隔符,它永远不会出现,它意味着“未分隔”。

因此,不需要无用地使用cat,也不需要重新组合数组。

此外,你还能得到这样的好处:

$ echo $EXAMPLE
Hello こんにちは 今晩は 小夜なら

你没有收到@Zombo的方法:

mapfile y <<'z'
abc'asdf"
$(dont-execute-this)
foo"bar"''
z
echo $y
abc'asdf"

奖金

如果你通过head -c -1运行它,你也可以用一种不会不性能的方式摆脱最后的换行:

unset EXAMPLE
mapfile -d '' EXAMPLE < <(head -c -1 << EOF
Hello
こんにちは
今晩は
小夜なら
EOF
)
printf "%q" "$EXAMPLE"
$'Hello\nこんにちは\n今晩は\n小夜なら'
$TEST="ok"
read MYTEXT <<EOT
this bash trick
should preserve
newlines $TEST
long live perl
EOT
echo -e $MYTEXT
VAR=<<END
abc
END

不工作,因为你将stdin重定向到不关心它的东西,即赋值

export A=`cat <<END
sdfsdf
sdfsdf
sdfsfds
END
` ; echo $A

有用,但里面有个背部痉挛可能会阻止你使用这个。另外,你应该避免使用反引号,最好使用命令替换符号$(..)。

export A=$(cat <<END
sdfsdf
sdfsdf
sdfsfds
END
) ; echo $A

使用$()将cat的输出赋值给你的变量,如下所示:

VAR=$(cat <<'END_HEREDOC'
abc'asdf"
$(dont-execute-this)
foo"bar"''
END_HEREDOC
)

# this will echo variable with new lines intact
echo "$VAR"
# this will echo variable without new lines (changed to space character)
echo $VAR

确保从END_HEREDOC开始用单引号分隔。

注意,结束括号分隔符END_HEREDOC必须单独在一行上(因此结束括号在下一行上)。

感谢@ephemient的回答。

将heredoc值赋给变量

VAR="$(cat <<'VAREOF'
abc'asdf"
$(dont-execute-this)
foo"bar"''
VAREOF
)"

用作命令的参数

echo "$(cat <<'SQLEOF'
xxx''xxx'xxx'xx  123123    123123
abc'asdf"
$(dont-execute-this)
foo"bar"''
SQLEOF
)"