Bash: Форматирование отступов

Возникло такое желание, оформить вывод скрипта построения как-то более красиво, то есть выровнять статус шага, например:

Configure.........................................OK
Build.............................................OK

Самую простую идею, как это сделать подсказал мой коллега ( привет Максим ) - это использовать echo и обрезание строк в bash, но все по порядку.

В начале, попробую собрать все конструкции bash которые нам понадобятся:

  • Работа со строками

    ${#string}  
    ${string:position} Извлечь строку($string) с позиции $position
    ${string:position:length} Извлечь строку с позиции ($position) длинной($length)
  • Арифметические выражения

    $((EXPRESSION)) арифметическое выражении - например $(( 2 * 2 ))

  • Локальные переменные

    Переменные деймствующие только в этом блоке, например.

    f() {
     local varlocal=1
    }
    echo 'varlocal is "' $varlocal '"'
    

    Вывод:

    varlocal is " "
    
  • Функции.

    function foo {
     echo "fun foo"
    }
    
    foo(){
     echo "foo"
    }
    

    Здесь все просто - функции. Причем второй вариант предпочтительнее, т.к. он, якобы, более совместим, со слов разработчиков bash

Вот в принципе и все, достаточно многовато, хотя можно обойтись и без локальных переменных и функций, но я за повторное использование кода :).

Итак, ниже будут приведены просто куски кода, без объяснений, надеюсь вы сами поймете, что к чему.

Выравнивание слева. Здесь в принципе без разницы используем мы ${string:position} или ${string:position:length}.

# DOTSTRING=`for i in {1..50}; do echo -n "."; done`
 DOTSTRING=".................................................."
 function align_left() {
    local chars="$1"
    local str="${@:2}"
    echo -n ${str}${chars:${#str}}
 }
 align_left $DOTSTRING "Hello"; echo "OK"
 align_left $DOTSTRING "BigBigString"; echo "OK"

Результат:

Hello.............................................OK
BigBigString......................................OK

Выравнивание справа:

DOTSTRING=".................................................."
function align_right() {
   local chars="$1"
   local str="${@:2}"
   echo -n ${chars:${#str}}${str}
}
echo -n "OK"; align_right $DOTSTRING "Hello"; echo
echo -n "OK"; align_right $DOTSTRING "BigBigString"; echo

Результат:

OK.............................................Hello
OK......................................BigBigString

Ну и на сладкое: выравнивание по центру.

DOTSTRING=".................................................."
function align_central() {
   local chars="$1"
   local str="${@:2}"
   local half=$(( (${#chars} - ${#str})/2 ))
   local rest=$(( ${#chars} - ${#str} - $half ))
   echo -n ${chars:0:$half}${str}${chars:0:$rest}
}
align_central $DOTSTRING " Hello "; echo
align_central $DOTSTRING " BigBigString "; echo

Результат:

..................... Hello ......................
.................. BigBigString ..................

Есть и альтернативное решение, например до варианта с echо я использовал printf.

printf "%s%*.*s" "$str" 0 $((${#chars} - ${#str})) "$chars"