如何打印带有填充中心对齐的变量?

如何打印带有填充中心对齐的变量?

如何打印$myvar填充,使其位于终端的中心,并且两侧均=位于屏幕边缘?

答案1

我在 stackexchange 网络上找到了两条信息,帮助我找到了这个可行的答案:

然而,这个答案中的代码是我自己的。

如果您想要更详细的内容,请参阅编辑历史记录;我已经删除了所有的废话和“一路走来的步骤”。


我认为最好的办法是:

center() {
  termwidth="$(tput cols)"
  padding="$(printf '%0.1s' ={1..500})"
  printf '%*.*s %s %*.*s\n' 0 "$(((termwidth-2-${#1})/2))" "$padding" "$1" 0 "$(((termwidth-1-${#1})/2))" "$padding"
}
center "Something I want to print"

终端上的输出 80 列宽:

========================== Something I want to print ===========================

请注意,填充不必是单个字符;也可以是单个字符。事实上padding变量不是,上面代码中的它有 500 个字符长。您可以通过仅更改行来使用其他形式的填充padding

padding="$(printf '%0.2s' ^v{1..500})"

结果是:

^v^v^v^v^v^v^v^v^v^v^v^v^v Something I want to print ^v^v^v^v^v^v^v^v^v^v^v^v^v^

另一个方便的用途是:

clear && center "This is my header"

答案2

zsh

$ var='some text'                                                              |
$ print -r - ${(l[COLUMNS/2][=]r[COLUMNS-COLUMNS/2][=])var}                    |
===================================some text===================================|

左侧 pad 和右侧 pad=的列数都是终端中的一半。使用该m标志,填充会考虑字符的宽度,以防 中存在零宽度或双宽度字符$var

使用bashGNU wc,您可以执行相同的操作:

var='some text'
width=$(wc -L <<< "$var")
printf -v pad "%$(( (COLUMNS - width) / 2 ))s"
pad=${pad// /=}
printf '%s%.*s\n' "$pad$var$pad" "$(((COLUMNS-width)%2))" =

我们使用 GNUwc -L来获取 的显示宽度$var。如果您的字符串仅包含单宽字符,width=${#var}则可以使用。

请注意,在任何情况下,这些假设$var都不包含控制字符(包括 TAB、NL、CR、着色转义序列等)。

答案3

这个命题看起来很实用,但意味着终端支持 terminfo 功能cols, hpa, ech, cuf, 和cud1, cf输出(1),术语信息(5),信息CMP(1m)。

#!/bin/bash

# Function "center_text": center the text with a surrounding border

# first argument: text to center
# second argument: glyph which forms the border
# third argument: width of the padding

center_text()
{
    local terminal_width=$(tput cols)    # query the Terminfo database: number of columns
    local text="${1:?}"                  # text to center
    local glyph="${2:-=}"                # glyph to compose the border
    local padding="${3:-2}"              # spacing around the text

    local border=                        # shape of the border
    local text_width=${#text}

    # the border is as wide as the screen
    for ((i=0; i<terminal_width; i++))
    do
        border+="${glyph}"
    done

    printf "$border"

    # width of the text area (text and spacing)
    local area_width=$(( text_width + (padding * 2) ))

    # horizontal position of the cursor: column numbering starts at 0
    local hpc=$(( (terminal_width - area_width) / 2 ))

    tput hpa $hpc                       # move the cursor to the beginning of the area

    tput ech $area_width                # erase the border inside the area without moving the cursor
    tput cuf $padding                   # move the cursor after the spacing (create padding)

    printf "$text"                      # print the text inside the area

    tput cud1                           # move the cursor on the next line
}

center_text "Something I want to print" "~"
center_text "Something I want to print" "=" 6

下面的命题比@更健壮、可扩展、更清晰通配符解决方案

#!/bin/bash

# Function "center_text": center the text with a surrounding border

# first argument: text to center
# second argument: glyph which forms the border
# third argument: width of the padding

center_text()
{

    local terminal_width=$(tput cols)     # query the Terminfo database: number of columns
    local text="${1:?}"                   # text to center
    local glyph="${2:-=}"                 # glyph to compose the border
    local padding="${3:-2}"               # spacing around the text

    local text_width=${#text}             

    local border_width=$(( (terminal_width - (padding * 2) - text_width) / 2 ))

    local border=                         # shape of the border

    # create the border (left side or right side)
    for ((i=0; i<border_width; i++))
    do
        border+="${glyph}"
    done

    # a side of the border may be longer (e.g. the right border)
    if (( ( terminal_width - ( padding * 2 ) - text_width ) % 2 == 0 ))
    then
        # the left and right borders have the same width
        local left_border=$border
        local right_border=$left_border
    else
        # the right border has one more character than the left border
        # the text is aligned leftmost
        local left_border=$border
        local right_border="${border}${glyph}"
    fi

    # space between the text and borders
    local spacing=

    for ((i=0; i<$padding; i++))
    do
        spacing+=" "
    done

    # displays the text in the center of the screen, surrounded by borders.
    printf "${left_border}${spacing}${text}${spacing}${right_border}\n"
}

center_text "Something I want to print" "~"
center_text "Something I want to print" "=" 6

答案4

你可以这样做

WIDTH=$(tput cols)
WIDTHDIVIDED=$(($WIDTH/2)) # Solves "tput cols divided by 2"
clear
tput cup 0 $WIDTHDIVIDED # Puts the start of the PS1 at column 0 and the terminal width divided by two

希望有帮助。

相关内容