1

我在 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之后连接内容。-----

我怎样才能达到我所需要的?

4

5 回答 5

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
于 2014-03-10T14:55:24.750 回答
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"
于 2014-03-10T14:59:40.460 回答
1

最简单的解决方法是只打印$CHANGES命令替换中的当前值:

CHANGES="$(print_revision $CURRENT_SHORT_REVISION; echo "$CHANGES")"
于 2014-03-10T15:31:25.127 回答
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 中附加一个标记来避免在其输出中出现换行符,然后在使用它时将其剥离:

function print_revision {
    printf "Revision %s (%s)\n%s\n\n___" ...
}

REVISION="$(print_revision $CURRENT_SHORT_REVISION)"
CHANGES="${REVISION%___}$CHANGES"
于 2014-03-10T14:53:05.393 回答
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,因此它可以用于创建或前置。

于 2014-03-10T15:07:36.313 回答