Bash printf 输出的函数有时缺少格式
Bash function with printf output missing formatting only sometimes
我有一个带有四个参数并输出格式化标题的函数。大部分时间此功能有效,但偶尔会决定无效。
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=
heading=
color=
fill=
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" "-"
Shell Output
这个想法是,所有标题最多可排成 100 个字符,并为少于 100 个字符的标题填充字符。
如您所见,有些标题没有对齐;虽然微不足道,但非常烦人(忽略未着色的标题——当我打印输出时变量被错误命名)。
我不知道是什么导致了某些标题出现问题。连接字符串时 Bash 是字符解释错误吗?
对于 h1/h2 你有 ${#formatted_ftitle} = 18/19
对于 even/odd ${#ftitle}
(即偶数=偶数,奇数=奇数)。
但是对于 h3 你有 ${#formatted_ftitle} = 27/28
和 even/odd ${#ftitle}
(即奇=偶,偶=奇)。
因此,看起来您不仅需要考虑填充符的 odd/even-ness,还需要考虑标题...在确定是否应该删除尾随字符时。
实际上,它看起来可以归结为只需要担心 ${#ftitle}
的 even/odd-ness,例如:
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=
heading=
color=
fill=
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 ---------------------------
我有一个带有四个参数并输出格式化标题的函数。大部分时间此功能有效,但偶尔会决定无效。
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=
heading=
color=
fill=
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" "-"
Shell Output
如您所见,有些标题没有对齐;虽然微不足道,但非常烦人(忽略未着色的标题——当我打印输出时变量被错误命名)。
我不知道是什么导致了某些标题出现问题。连接字符串时 Bash 是字符解释错误吗?
对于 h1/h2 你有 ${#formatted_ftitle} = 18/19
对于 even/odd ${#ftitle}
(即偶数=偶数,奇数=奇数)。
但是对于 h3 你有 ${#formatted_ftitle} = 27/28
和 even/odd ${#ftitle}
(即奇=偶,偶=奇)。
因此,看起来您不仅需要考虑填充符的 odd/even-ness,还需要考虑标题...在确定是否应该删除尾随字符时。
实际上,它看起来可以归结为只需要担心 ${#ftitle}
的 even/odd-ness,例如:
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=
heading=
color=
fill=
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 ---------------------------