用空格缩进heredocs [英] Indenting heredocs with spaces
问题描述
对于我从事的个人开发和项目,我们使用四个空格代替制表符. 但是,我需要使用Heredoc,并且我必须在不中断缩进流程的情况下使用它.
For personal development and projects I work on, we use four spaces instead of tabs. However, I need to use a heredoc, and I can't do so without breaking the indention flow.
我能想到的唯一可行的方法是:
The only working way to do this I can think of would be this:
usage() {
cat << ' EOF' | sed -e 's/^ //';
Hello, this is a cool program.
This should get unindented.
This code should stay indented:
something() {
echo It works, yo!;
}
That's all.
EOF
}
有更好的方法吗?
让我知道它是否属于 Unix/Linux Stack Exchange .
推荐答案
(如果您使用的是bash
4,请滚动到最后,我认为这是纯shell和可读性的最佳组合.)
(If you are using bash
4, scroll to the end for what I think is the best combination of pure shell and readability.)
对于shell脚本,使用制表符不是偏好或样式的问题;这就是语言的定义方式.
For shell scripts, using tabs is not a matter of preference or style; it's how the language is defined.
usage () {
⟶# Lines between EOF are each indented with the same number of tabs
⟶# Spaces can follow the tabs for in-document indentation
⟶cat <<-EOF
⟶⟶Hello, this is a cool program.
⟶⟶This should get unindented.
⟶⟶This code should stay indented:
⟶⟶ something() {
⟶⟶ echo It works, yo!;
⟶⟶ }
⟶⟶That's all.
⟶EOF
}
另一种选择是完全避免使用此处的文档,但必须使用更多的引号和换行符:
Another option is to avoid a here document altogether, at the cost of having to use more quotes and line continuations:
usage () {
printf '%s\n' \
"Hello, this is a cool program." \
"This should get unindented." \
"This code should stay indented:" \
" something() {" \
" echo It works, yo!" \
" }" \
"That's all."
}
如果您愿意放弃POSIX兼容性,则可以使用数组来避免显式的行继续:
If you are willing to forego POSIX compatibility, you can use an array to avoid the explicit line continuations:
usage () {
message=(
"Hello, this is a cool program."
"This should get unindented."
"This code should stay indented:"
" something() {"
" echo It works, yo!"
" }"
"That's all."
)
printf '%s\n' "${message[@]}"
}
以下内容再次使用here文档,但是这次使用bash
4的readarray
命令填充数组.参数扩展用于从每个谎言的开头删除固定数量的空格.
The following uses a here document again, but this time with bash
4's readarray
command to populate an array. Parameter expansion takes care of removing a fixed number of spaces from the beginning of each lie.
usage () {
# No tabs necessary!
readarray message <<' EOF'
Hello, this is a cool program.
This should get unindented.
This code should stay indented:
something() {
echo It works, yo!;
}
That's all.
EOF
# Each line is indented an extra 8 spaces, so strip them
printf '%s' "${message[@]# }"
}
最后一个变体:您可以使用扩展模式来简化参数扩展.不必计算缩进使用了多少空格,只需以所选的非空格字符结束缩进,然后匹配固定前缀即可.我使用:
. (以下空格
冒号是为了提高可读性;只需稍加更改前缀模式就可以删除它.)
One last variation: you can use an extended pattern to simplify the parameter expansion. Instead of having to count how many spaces are used for indentation, simply end the indentation with a chosen non-space character, then match the fixed prefix. I use :
. (The space following
the colon is for readability; it can be dropped with a minor change to the prefix pattern.)
(此外,使用以空格开头的here-doc分隔符的一个很好的技巧的一个缺点是,它会阻止您在here-doc内执行扩展.如果您想这样做,您可以要么必须保留定界符不缩进,要么对您的无制表符规则做一个小小的例外,并使用<<-EOF
和制表符为缩进的结束定界符.)
(Also, as an aside, one drawback to your very nice trick of using a here-doc delimiter that starts with whitespace is that it prevents you from performing expansions inside the here-doc. If you wanted to do so, you'd have to either leave the delimiter unindented, or make one minor exception to your no-tab rule and use <<-EOF
and a tab-indented closing delimiter.)
usage () {
# No tabs necessary!
closing="That's all"
readarray message <<EOF
: Hello, this is a cool program.
: This should get unindented.
: This code should stay indented:
: something() {
: echo It works, yo!;
: }
: $closing
EOF
shopt -s extglob
printf '%s' "${message[@]#+( ): }"
shopt -u extglob
}
这篇关于用空格缩进heredocs的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!