在bash中有效地重用printf%s替换中的颜色代码

时间:2017-02-14 19:56:35

标签: bash printf

biwhite=$(tput bold)$(tput setaf 7)
color_off=$(tput sgr0)

printf "%s$USER%s at %s$HOME%s has path %s$PATH%s" "$biwhite" "$color_off" "$biwhite" "$color_off" "$biwhite" "$color_off"

是否有printf快捷方式,以避免在我只想为语句的某些部分添加颜色时必须定义每个%s

输入"$biwhite" "$color_off" 3次似乎是多余的。

3 个答案:

答案 0 :(得分:2)

避免将参数扩展放在printf的格式字符串中,以防它们包含百分号,这是一种很好的做法。也就是说,参数替换提供了解决某些重复性的方法。

w="${biwhite}X${color_off}"

printf "%s at %s has path %s" "${w/X/$USER}" "${w/X/$HOME}" "${w/X/$PATH}"

这不是万无一失的,但X输出tput的可能性相当小。您可以选择更长的字符串,但需要输入更多内容。

但是,我担心,在字符串中添加颜色代码本身就很痛苦。

答案 1 :(得分:1)

我认为你可以写一个bash函数:

biwhite=$(tput bold)$(tput setaf 7)
color_off=$(tput sgr0)

whiten() {
  echo "$biwhite$1$color_off"
}

echo "$(whiten "$USER") at $(whiten "$HOME") has path $(whiten "$PATH")"

另外,如果您没有使用任何格式化功能,为什么要使用printf

答案 2 :(得分:0)

下面提供的是一个从第二个开始着色所有其他参数的函数。 (因此,可以通过在第一个位置传递非空字符串来提供非着色前缀,或者通过将其留空来为其提供颜色,如此处所示。)

值得注意的是,除了用于演示目的的tput调用之外,此代码的执行不涉及子shell。因此,虽然冗长,但执行起来的开销很低。

biwhite=$(tput bold)$(tput setaf 7)
color_off=$(tput sgr0)

# colorize every other argument, starting from the 2nd.
colorize_words() {
  local start_color end_color
  : "${start_color:=$biwhite}" "${end_color:=$color_off}"
  while (( $# )); do
    printf '%s' "$1"
    shift || break
    printf '%s%s%s' "$start_color" "$1" "$end_color"
    shift || break
  done
  printf '\n'
}

colorize_words "" "$USER" " at " "$HOME" " has path " "$PATH"

可以通过将start_colorend_color值传递给单个调用来自定义;例如:

# this prints every other argument in red
start_color=$(tput setaf 1) colorize_words "hello " "cruel " world