Padding characters in printf

前端 未结 13 778
半阙折子戏
半阙折子戏 2020-11-30 16:58

I am writing a bash shell script to display if a process is running or not.

So far, I got this:

printf \"%-50s %s\\n\" $PROC_NAME [UP]
相关标签:
13条回答
  • 2020-11-30 17:47

    If you are ending the pad characters at some fixed column number, then you can overpad and cut to length:

    # Previously defined:
    # PROC_NAME
    # PROC_STATUS
    
    PAD="--------------------------------------------------"
    LINE=$(printf "%s %s" "$PROC_NAME" "$PAD" | cut -c 1-${#PAD})
    printf "%s %s\n" "$LINE" "$PROC_STATUS"
    
    0 讨论(0)
  • 2020-11-30 17:48

    Simple Console Span/Fill/Pad/Padding with automatic scaling/resizing Method and Example.

    function create-console-spanner() {
        # 1: left-side-text, 2: right-side-text
        local spanner="";
        eval printf -v spanner \'"%0.1s"\' "-"{1..$[$(tput cols)- 2 - ${#1} - ${#2}]}
        printf "%s %s %s" "$1" "$spanner" "$2";
    }
    

    Example: create-console-spanner "loading graphics module" "[success]"

    Now here is a full-featured-color-character-terminal-suite that does everything in regards to printing a color and style formatted string with a spanner.

    # Author: Triston J. Taylor <pc.wiz.tt@gmail.com>
    # Date: Friday, October 19th, 2018
    # License: OPEN-SOURCE/ANY (NO-PRODUCT-LIABILITY OR WARRANTIES)
    # Title: paint.sh
    # Description: color character terminal driver/controller/suite
    
    declare -A PAINT=([none]=`tput sgr0` [bold]=`tput bold` [black]=`tput setaf 0` [red]=`tput setaf 1` [green]=`tput setaf 2` [yellow]=`tput setaf 3` [blue]=`tput setaf 4` [magenta]=`tput setaf 5` [cyan]=`tput setaf 6` [white]=`tput setaf 7`);
    
    declare -i PAINT_ACTIVE=1;
    
    function paint-replace() {
        local contents=$(cat)
        echo "${contents//$1/$2}"
    }
    
    source <(cat <<EOF
    function paint-activate() {
        echo "\$@" | $(for k in ${!PAINT[@]}; do echo -n paint-replace \"\&$k\;\" \"\${PAINT[$k]}\" \|; done) cat;
    }
    EOF
    )
    
    source <(cat <<EOF
    function paint-deactivate(){
        echo "\$@" | $(for k in ${!PAINT[@]}; do echo -n paint-replace \"\&$k\;\" \"\" \|; done) cat;    
    }
    EOF
    )
    
    function paint-get-spanner() {
        (( $# == 0 )) && set -- - 0;
        declare -i l=$(( `tput cols` - ${2}))
        eval printf \'"%0.1s"\' "${1:0:1}"{1..$l}
    }
    
    function paint-span() {
        local left_format=$1 right_format=$3
        local left_length=$(paint-format -l "$left_format") right_length=$(paint-format -l "$right_format")
        paint-format "$left_format";
        paint-get-spanner "$2" $(( left_length + right_length));
        paint-format "$right_format";
    }
    
    function paint-format() {
        local VAR="" OPTIONS='';
        local -i MODE=0 PRINT_FILE=0 PRINT_VAR=1 PRINT_SIZE=2;
        while [[ "${1:0:2}" =~ ^-[vl]$ ]]; do
            if [[ "$1" == "-v" ]]; then OPTIONS=" -v $2"; MODE=$PRINT_VAR; shift 2; continue; fi;
            if [[ "$1" == "-l" ]]; then OPTIONS=" -v VAR"; MODE=$PRINT_SIZE; shift 1; continue; fi;
        done;
        OPTIONS+=" --"
        local format="$1"; shift;
        if (( MODE != PRINT_SIZE && PAINT_ACTIVE )); then
            format=$(paint-activate "$format&none;")
        else
            format=$(paint-deactivate "$format")
        fi
        printf $OPTIONS "${format}" "$@";
        (( MODE == PRINT_SIZE )) && printf "%i\n" "${#VAR}" || true;
    }
    
    function paint-show-pallette() {
        local -i PAINT_ACTIVE=1
        paint-format "Normal: &red;red &green;green &blue;blue &magenta;magenta &yellow;yellow &cyan;cyan &white;white &black;black\n";
        paint-format "  Bold: &bold;&red;red &green;green &blue;blue &magenta;magenta &yellow;yellow &cyan;cyan &white;white &black;black\n";
    }
    

    To print a color, that's simple enough: paint-format "&red;This is %s\n" red And you might want to get bold later on: paint-format "&bold;%s!\n" WOW

    The -l option to the paint-format function measures the text so you can do console font metrics operations.

    The -v option to the paint-format function works the same as printf but cannot be supplied with -l

    Now for the spanning!

    paint-span "hello " . " &blue;world" [note: we didn't add newline terminal sequence, but the text fills the terminal, so the next line only appears to be a newline terminal sequence]

    and the output of that is:

    hello ............................. world

    0 讨论(0)
  • 2020-11-30 17:49

    There's no way to pad with anything but spaces using printf. You can use sed:

    printf "%-50s@%s\n" $PROC_NAME [UP] | sed -e 's/ /-/g' -e 's/@/ /' -e 's/-/ /'
    
    0 讨论(0)
  • 2020-11-30 17:54

    This one is even simpler and execs no external commands.

    $ PROC_NAME="JBoss"
    $ PROC_STATUS="UP"
    $ printf "%-.20s [%s]\n" "${PROC_NAME}................................" "$PROC_STATUS"
    
    JBoss............... [UP]
    
    0 讨论(0)
  • 2020-11-30 17:55

    Trivial (but working) solution:

    echo -e "---------------------------- [UP]\r$PROC_NAME "
    
    0 讨论(0)
  • 2020-11-30 17:56

    Simple but it does work:

    printf "%-50s%s\n" "$PROC_NAME~" "~[$STATUS]" | tr ' ~' '- '
    

    Example of usage:

    while read PROC_NAME STATUS; do  
        printf "%-50s%s\n" "$PROC_NAME~" "~[$STATUS]" | tr ' ~' '- '
    done << EOT 
    JBoss DOWN
    GlassFish UP
    VeryLongProcessName UP
    EOT
    

    Output to stdout:

    JBoss -------------------------------------------- [DOWN]
    GlassFish ---------------------------------------- [UP]
    VeryLongProcessName ------------------------------ [UP]
    
    0 讨论(0)
提交回复
热议问题