Kam*_*man 9 variables bash escaping heredoc
有没有办法让Bash heredoc在heredoc中解释'\n \'?
我在循环中有一个迭代构建的字符串,类似于
for i in word1 word2 word3
do
TMP_VAR=$i
ret="$ret\n$TMP_VAR"
done
Run Code Online (Sandbox Code Playgroud)
然后我想在heredoc中使用创建的字符串:
cat <<EOF > myfile
HEADER
==
$ret
==
TRAILER
EOF
Run Code Online (Sandbox Code Playgroud)
但是我想将"\n"字符解释为换行符,以便输出为
HEADER
==
word1
word2
word3
==
TRAILER
Run Code Online (Sandbox Code Playgroud)
代替
HEADER
==
\nword1\nword2\nword3
==
TRAILER
Run Code Online (Sandbox Code Playgroud)
可能吗?或者我应该以某种方式构建我的初始字符串?
Tom*_*ech 10
在bash中,您可以使用$'\n'向字符串添加换行符:
ret="$ret"$'\n'"$TMP_VAR"
Run Code Online (Sandbox Code Playgroud)
您还可以使用+=附加到字符串:
ret+=$'\n'"$TMP_VAR"
Run Code Online (Sandbox Code Playgroud)
正如其他人(以及其他问题的其他答案)所说,您可以将编码的字符放入字符串中以供shell解释.
x=$'\n' # newline
printf -v x '\n' # newline
Run Code Online (Sandbox Code Playgroud)
也就是说,我不相信有任何方法可以直接将编码的换行符放入heredoc.
cat <<EOF
\n
EOF
Run Code Online (Sandbox Code Playgroud)
只输出一个文字 \n
cat <<$'EOF'
…
EOF
Run Code Online (Sandbox Code Playgroud)
没什么特别的,也不是 <<'EOF'
您可以做的最好的事情是对换行符进行预编码,并在heredoc中包含扩展:
nl=$'\n'
cat <<EOF
foo bar $nl baz
EOF
Run Code Online (Sandbox Code Playgroud)
输出
foo bar
baz
Run Code Online (Sandbox Code Playgroud)
最好的解决方案是用实际的换行符构建变量,而不是插入需要用换行符替换的字符序列。
我发现以下功能非常有用,因此我将其放入我的 bash 启动文件中;对于你简单的情况,它会完美地工作:
lines() { printf %s\\n "$@"; }
Run Code Online (Sandbox Code Playgroud)
有了这个,你可以写:
ret=$(lines word1 word2 word3)
Run Code Online (Sandbox Code Playgroud)
而不是您使用的循环。然后你可以插入$ret到 heredoc 中,它会按预期工作。[见注1]
但是,如果出于某种原因,您确实想使用转义序列而不是实际字符来构造字符串,则可以使用 bashprintf内置%b格式代码中的扩展功能进行扩展。%b执行几乎相同的转义转换,但有一些差异。详情请参阅help printf。使用它,您可以执行以下操作:
$ ret="word1\nword2\nword3"
$ cat <<EOF > tmp
> HEADER
> ==
> $(printf "%b" "$ret")
> ==
> TRAILER
> EOF
$ cat tmp
HEADER
==
word1
word2
word3
==
TRAILER
Run Code Online (Sandbox Code Playgroud)
lines函数的使用有一个微妙之处。printf不断重复它的格式字符串,直到它吸收所有参数,以便格式%s\\n在每个参数后放置一个换行符,包括最后一个。对于大多数用例,这正是您想要的;我对线的大部分使用都与将结果输入到需要输入线的实用程序有关。
但是在 的情况下ret=$(lines word1 word2 word3),我真的不想要尾随换行符,因为我的计划是$ret在此处的文档中单独插入一行。幸运的是,命令替换 ( $(...)) 总是从命令的输出中删除尾随的换行符,因此ret赋值之后的值在参数之间有换行符,但在末尾没有。(此功能偶尔会令人讨厌,但更多时候它正是您想要的,因此不会引起注意。)
小智 5
更改:
==
$ret
==
Run Code Online (Sandbox Code Playgroud)
至:
==
$(echo -e $ret)
==
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
7701 次 |
| 最近记录: |