是否可以更改终端中的字体颜色,而不会影响printf的“%* s”填充格式?

Modified on: Sat, 30 Jun 2018 12:12:00 +0800

我在bash脚本中有一个函数:message_offset,用于打印bash脚本的状态。
即你可以称之为将消息传递给它和状态,如此

message_offset "install font library" "[   OK   ]" 

它将打印到终端,其中printf%*s格式用于始终设置[ OK ] 80列宽
例如输出将是

install font library                              [   OK   ]
update configuration file on server               [   ERR  ]
                                                           ^
                                                           |
                                                      always
                                                        at 80

如果使用echo,输出将如下所示

install font library                 [   OK   ]
update configuration file on server               [   ERR  ]

代码:

#!/usr/bin/env bash

function message_offset() {

    local message="$1"
    local status="$2"

    # compensate for the message length by reducing the offset 
    # by the length of the message, 
    (( offset = 80 - ${#message} ))

    # add a $(tput sgr0) to the end to "exit attributes" whether a color was
    # set or not
    printf "%s%*s%s" "${message}" 80 "$status" "$(tput sgr0)"

}

这一切都正常,直到我尝试使用tput将一些颜色序列添加到字符串中,即使“[ERR]”变为红色。
似乎printf "%*s"格式正在计算中
设置偏移时的tput字符序列,所以如果我调用这个函数

message_offset "update configuration file on server"  "$(tput setaf 1)[   ERR  ]"

输出看起来像:

install font library                              [   OK   ]
update configuration file on server          [   ERR  ]

因为printf "%*s"说这个字符串已经包含了所有"[ ERR ]"字符,加上"$(tput setaf 1)字符,但很明显"$(tput setaf 1)字符不打印,因此实际上不会影响填充。
有没有办法可以为“状态”消息添加颜色,还可以使用tput样式颜色序列?

最佳答案

你让它变得比它应该复杂得多。您可以使用$message处理对齐,而不关心ANSI序列的宽度:

#! /usr/bin/env bash

message() {
    [ x"$2" = xOK ] && color=2 || color=1
    let offset=$(tput cols)-4-${#2}
    printf "%-*s[ %s%s%s ]\n" $offset "$1" "$(tput setaf "$color")"  "$2" "$(tput sgr0)"
}  

message "install font library" "OK"
message "update configuration file on server" "ERR"

编辑:请注意,大多数printf(1)实现都无法很好地处理多字节字符集的长度计算。因此,如果要在UTF-8中打印带有重音字符的消息,则可能需要采用不同的方法。 耸肩


相关问答

添加新评论