简体   繁体   English

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

[英]Efficiently reusing color codes in a printf %s substitution in bash

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"

Is there a printf shortcut to avoid having to define every %s when I want to add color to only certain parts of a statement? 是否有一个printf快捷方式,以避免在我只想为语句的某些部分添加颜色时必须定义每个%s

Entering "$biwhite" "$color_off" 3 times seems redundant. 输入"$biwhite" "$color_off" 3次似乎是多余的。

It's good practice to avoid putting parameter expansions in the format string of printf , in case they contain percent signs as well. 避免将参数扩展放在printf的格式字符串中是好的做法,以防它们包含百分号。 That said, parameter substitution offers a way around some of the repetitiveness. 也就是说,参数替换提供了解决某些重复性的方法。

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

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

It's not foolproof, but it's fairly unlikely that X will appear in the output of tput . 这不是万无一失的,但X可能出现在tput的输出中。 You can pick a longer string instead, at the cost of more typing. 您可以选择更长的字符串,但需要输入更多内容。

I'm afraid, though, that adding color codes to a string is inherently painful. 但我担心,在字符串中添加颜色代码本身就很痛苦。

I think you could write a bash function: 我想你可以写一个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")"

Also, why use printf if you're not using any of it's formatting capabilities? 另外,如果您没有使用任何格式化功能,为什么要使用printf

Provided below is a function which colorizes every other argument, starting with the second. 下面提供的是一个从第二个开始着色所有其他参数的函数。 (Thus, a non-colorized prefix can be provided by passing a non-empty string in this first position, or a colorized one by leaving it empty, as here). (因此,可以通过在第一个位置传递非空字符串来提供非着色前缀,或者通过将其留空来为其着色,如此处所示)。

Notably, no subshells are involved in this code's execution except in the tput invocations used for demonstrative purposes. 值得注意的是,除了用于演示目的的tput调用之外,此代码的执行中不涉及子shell。 It is thus, while verbose, very low-overhead to execute. 因此,虽然冗长,但执行起来非常低。

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"

This can be customized by passing start_color and end_color values to an individual invocation; 这可以通过将start_colorend_color值传递给单个调用来自定义; for example: 例如:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM