在bash中的printf%s替换中高效地重用颜色代码
当我只想给语句的某些部分添加颜色时,是否有一个在bash中的printf%s替换中高效地重用颜色代码,bash,printf,Bash,Printf,当我只想给语句的某些部分添加颜色时,是否有一个printf快捷方式来避免必须定义每个%s 输入“$biwhite”“$color\u off”三次似乎是多余的。我认为您可以编写一个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" "$colo
printf
快捷方式来避免必须定义每个%s
输入
“$biwhite”“$color\u off”
三次似乎是多余的。我认为您可以编写一个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"
另外,如果没有使用任何格式化功能,为什么要使用
printf
?最好避免在printf
的格式字符串中放置参数展开,以防它们也包含百分号。也就是说,参数替换提供了一种绕过某些重复性的方法
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")"
这不是万无一失的,但是X
不太可能出现在tput
的输出中。你可以选择一个更长的字符串来代替,但要付出更多的输入代价
不过,我担心在字符串中添加颜色代码本身就是一件痛苦的事情。下面提供的是一个函数,它可以从第二个参数开始为其他每个参数着色。(因此,可以通过在第一个位置传递非空字符串来提供非彩色前缀,或者通过将其保留为空来提供彩色前缀,如下所示) 值得注意的是,除了用于说明目的的
tput
调用之外,此代码的执行中不涉及子shell。因此,虽然冗长,但执行的开销非常低
w="${biwhite}X${color_off}"
printf "%s at %s has path %s" "${w/X/$USER}" "${w/X/$HOME}" "${w/X/$PATH}"
这可以通过向单个调用传递start\u color
和end\u color
值来定制;例如:
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"
真正的问题是,为什么要使用
echo
而不是printf
?此外,您建议OP用大量子shell替换好的代码。。。这不是很好。在一些常见情况下,使用printf
而不是echo
是由…echo
直接建议的。在一些常见情况下,标准未定义echo的行为(并且实现之间存在差异),特别是在传递的参数可能包含反斜杠文字的任何情况下。值得注意的是,在启用和不启用xpg_echo
标志的情况下(以及在启用和不启用posix
标志以及xpg_echo
的情况下),bash的行为是这些分歧点之一。这不是一个不合理的问题——许多其他语言都有在格式字符串中引用特定位置参数的方法。比如zsh
?Ducks你不应该把$USER
、$HOME
和$PATH
放在格式字符串中,因为你可能不想把$biwhite
和$color\u关闭
放在格式字符串中:如果它们包含百分号,你就有问题了。每个人都给出了非常好的答案!我之所以选择@chepner,是因为我认为答案“恐怕在字符串中添加色码本身就是痛苦的。”可能是最有用的答案:|非常感谢你,查尔斯。你总是有很好的答案。
# this prints every other argument in red
start_color=$(tput setaf 1) colorize_words "hello " "cruel " world