Функция Bash с выводом printf пропускает форматирование только иногда - PullRequest
0 голосов
/ 25 сентября 2019

У меня есть функция, которая принимает четыре параметра и выводит форматированный заголовок.Большую часть времени эта функция работает, но иногда она решает, что нет.

yelB=$'\e[1;33m'
fclr=$'\e[0m'

format_title() {
    # USAGE
    #   format_title "TITLE" "{h1/h2/h3}" "${color}" "{fill_character}"
    # EXMAPLE
    #   format_title "Heading 1" "h2" "$yelB" "="
    #   ============================ Heading 1 ============================

    ftitle=$1
    heading=$2
    color=$3
    fill=$4

    total_length=100
    ftitle_spacing=" "
    ftitle_border=$'\n' # variable implemented in h1 instances only
    formatted_ftitle=""

    if [[ $heading == "h1" ]]; then
        for (( i=1; i<=$total_length; i++ )); do
            ftitle_border=$ftitle_border$fill
        done
    fi

    if [[ $heading == "h1" || $heading == "h2" ]]; then
        ftitle_spacing="          "
    fi

    ftitle_fill=$(( ( $total_length / 2 ) - ( ${#ftitle} / 2 ) - ${#ftitle_spacing} ))

    for (( i=0; i<=$ftitle_fill; i++ )); do
        formatted_ftitle=$formatted_ftitle$fill

        if (( i == $ftitle_fill - 1 )); then

            formatted_ftitle=$formatted_ftitle$ftitle_spacing$color$ftitle$fclr$ftitle_spacing$formatted_ftitle

            # Check if the fill will be even or odd; if odd, remove the last fill character
            if (( $ftitle_fill % 2 )); then
                formatted_ftitle="${formatted_ftitle::-1}"
            fi

            if [[ $heading == "h1" ]]; then
                formatted_ftitle=$ftitle_border$'\n'$formatted_ftitle$ftitle_border$'\n'
            fi

            break
        fi
    done

    printf "%s\n" "$formatted_ftitle"
}

format_title "TEST HEADING ONE WITH EVEN NUMBER CHARACTERS" "h1" "$yelB" "#"
format_title "TEST HEADING TWO WITH ODD NUMBER CHARACTERS" "h1" "$yelB" "#"
format_title "TEST HEADING ONE WITH EVEN NUMBER CHARACTERS" "h2" "$yelB" "="
format_title "TEST HEADING TWO WITH ODD NUMBER CHARACTERS" "h2" "$yelB" "="
format_title "TEST HEADING ONE WITH EVEN NUMBER CHARACTERS" "h3" "$yelB" "-"
format_title "TEST HEADING TWO WITH ODD NUMBER CHARACTERS" "h3" "$yelB" "-"

Вывод оболочки https://i.stack.imgur.com/aTBGV.png Идея состоит в том, что все заголовки соответствуютмаксимум 100 символов с символом заполнения для заголовков длиной менее 100 символов.

Как видите, некоторые заголовки не совпадают;хотя это тривиально, это очень раздражает (игнорируйте неокрашенный заголовок - переменная была неправильно названа, когда я печатал вывод).

Я не могу понять, что является причиной проблемы некоторых заголовков.Это ошибка интерпретации символов в Bash при объединении строк?

1 Ответ

0 голосов
/ 25 сентября 2019

Для h1 / h2 у вас есть ${#formatted_ftitle} = 18/19 для четного / нечетного ${#ftitle} соответственно (т. Е. Четного = четного, нечетного = нечетного).

Но для h3 у вас есть ${#formatted_ftitle} = 27/28 для четного /odd ${#ftitle} соответственно (т.е. нечетный = четный, четный = нечетный).

Таким образом, похоже, что вам нужно учитывать не только нечетность / четность наполнителя, но и заголовок... при определении, следует ли вам убрать завершающий символ.

На самом деле это выглядит так, будто все сводится к необходимости беспокоиться о четности / нечетности ${#ftitle}, например:

yelB=$'\e[1;33m'
fclr=$'\e[0m'

format_title() {
    # USAGE
    #   format_title "TITLE" "{h1/h2/h3}" "${color}" "{fill_character}"
    # EXMAPLE
    #   format_title "Heading 1" "h2" "$yelB" "="
    #   ============================ Heading 1 ============================

    ftitle=$1
    heading=$2
    color=$3
    fill=$4

    total_length=100
    ftitle_spacing=" "
    ftitle_border=$'\n' # variable implemented in h1 instances only
    formatted_ftitle=""

    if [[ $heading == "h1" ]]; then
        for (( i=1; i<=$total_length; i++ )); do
            ftitle_border=$ftitle_border$fill
        done
    fi

    if [[ $heading == "h1" || $heading == "h2" ]]; then
        ftitle_spacing="          "
    fi

    ftitle_fill=$(( ( $total_length / 2 ) - ( ${#ftitle} / 2 ) - ${#ftitle_spacing} ))

    for (( i=0; i<$ftitle_fill; i++ )); do
        formatted_ftitle=$formatted_ftitle$fill
    done

    formatted_ftitle=$formatted_ftitle$ftitle_spacing$color$ftitle$fclr$ftitle_spacing$formatted_ftitle

    # if the length of ftitle is odd, remove the last fill character

    if (( ${#ftitle} % 2 )); then
        formatted_ftitle="${formatted_ftitle::-1}"
    fi


    if [[ $heading == "h1" ]]; then
        formatted_ftitle=$ftitle_border$'\n'$formatted_ftitle$ftitle_border$'\n'
    fi

    printf "%s\n" "${formatted_ftitle}"
}

format_title "TEST HEADING ONE WITH EVEN NUMBER CHARACTERS" "h1" "$yelB" "#"
format_title "TEST HEADING TWO WITH ODD NUMBER CHARACTERS" "h1" "$yelB" "#"
format_title "TEST HEADING ONE WITH EVEN NUMBER CHARACTERS" "h2" "$yelB" "="
format_title "TEST HEADING TWO WITH ODD NUMBER CHARACTERS" "h2" "$yelB" "="
format_title "TEST HEADING ONE WITH EVEN NUMBER CHARACTERS" "h3" "$yelB" "-"
format_title "TEST HEADING TWO WITH ODD NUMBER CHARACTERS" "h3" "$yelB" "-"

####################################################################################################
##################          TEST HEADING ONE WITH EVEN NUMBER CHARACTERS          ##################
####################################################################################################


####################################################################################################
###################          TEST HEADING TWO WITH ODD NUMBER CHARACTERS          ##################
####################################################################################################

==================          TEST HEADING ONE WITH EVEN NUMBER CHARACTERS          ==================
===================          TEST HEADING TWO WITH ODD NUMBER CHARACTERS          ==================
--------------------------- TEST HEADING ONE WITH EVEN NUMBER CHARACTERS ---------------------------
---------------------------- TEST HEADING TWO WITH ODD NUMBER CHARACTERS ---------------------------
...