我在bash中定义了以下函数:
function print_revision {
printf "Revision %s (%s)\n%s\n\n" "$1" "$(date --utc +%d.%m.%Y,\ %H:%M\ UTC)" \
"----------------------------------------"
}
我还有一个变量$CHANGES
,里面有一些文字。我需要做的是将print_revision
中打印的字符串添加到$CHANGES
变量中。
我已经尝试了以下但它似乎不起作用:
CHANGES="$(print_revision $CURRENT_SHORT_REVISION)"$CHANGES
它包含print_revision
之内的所有内容,但它会遍历最后两个换行符,在$CHANGES
部分之后连接-----
的内容。
我如何实现我的需要?
答案 0 :(得分:4)
请勿在此处使用命令替换。
printf -v var_name format_string arg1 arg2 ...
...将printf的输出直接存储到var_name
中,不涉及任何子shell(效率更高!),并且没有命令替换(没有删除尾随换行符!)
因此:
print_revision_to() {
printf -v "$1" \
"Revision %s (%s)\n%s\n\n" \
"$2" \
"$(date --utc +%d.%m.%Y,\ %H:%M\ UTC)" \
"----------------------------------------"
}
# ...thus, to put a header for revision 13 into "$changes", you'd run...
print_revision_to changes 13
......或者,如果你想一次性完成这件事......
prepend_revision_header_to() {
printf -v "$1" \
"Revision %s (%s)\n%s\n\n%s" \
"$2" \
"$(date --utc +%d.%m.%Y,\ %H:%M\ UTC)" \
"----------------------------------------"
"${!1}"
}
# ...thus, to modify the existing value of "$changes" by putting a header
# at the beginning, you'd run...
prepend_revision_header_to changes 13
答案 1 :(得分:2)
命令替换剥离字符串末尾的换行符。典型的用例是输出以换行符结束,要么打印另一个换行符,要么与另一个换行符串联以组成一行(例如echo $(echo part1)$(echo part2)
)。
如果您无法或不想更改print_revision
功能,请在其后打印非换行符,然后将其删除。
new_revision=$(print_revision $CURRENT_SHORT_REVISION; echo a); new_revision=${new_revision%a}
CHANGES=$new_revision$CHANGES
或者,在连接中添加任意数量的换行符。
CHANGES="$(print_revision $CURRENT_SHORT_REVISION)
$CHANGES"
答案 2 :(得分:1)
$ man bash
...
Command Substitution
...
Bash performs the expansion by executing command and replacing the com‐
mand substitution with the standard output of the command, with any
trailing newlines deleted.
因此,$(...)的使用正在删除尾随的换行符。
如果你想保留一个单独的print_revision函数,那么一种方法是通过在print_revision中附加一个sentinel来避免在其输出中尾随换行符,然后在你使用它时将其剥离:
function print_revision {
printf "Revision %s (%s)\n%s\n\n___" ...
}
REVISION="$(print_revision $CURRENT_SHORT_REVISION)"
CHANGES="${REVISION%___}$CHANGES"
答案 3 :(得分:1)
一种可能性是将现有值(如果有)传递给函数:
prepend_revision() {
printf "Revision %s (%s)\n%s\n\n%s" \
"$1" "$(date --utc +%d.%m.%Y,\ %H:%M\ UTC)" \
"----------------------------------------" "$2"
}
CHANGES=$(prepend_revision "$CURRENT_SHORT_REVISION" "$CHANGES")
请注意,如果仅使用一个参数调用prepend_revision
,则输出与现有的print_revision
函数完全相同,因此可用于创建或添加。
答案 4 :(得分:1)
最简单的解决方法是在命令替换中打印$CHANGES
的当前值:
CHANGES="$(print_revision $CURRENT_SHORT_REVISION; echo "$CHANGES")"