Хеллоу! Попался мне вчера чей-то очередной bash скрипт, в котором были такие конструкции:

echo '--------------' 
printf '%s\n' '--------------'

Так-то нормальная практика, но смотрится как-то уж очень непрофессионально. У python и прочих языков такое можно реализовать примерно так:

python3 -c 'print("-" * 80)'
perl -E 'say "-" x 80'

А что же с bash? Из коробки такой функции увы нет. Включаем «режим изобретателя». Поехали.

repeat(){
    for i in {1..90}; do echo -n "$1"; done
}

repeat '-'

Создаём функцию с циклом repeat, в которую передадим символ «-» для повторения 90 раз. Вот оно! Уже намного лучше.

Теперь если мне нужно вывести какие-то заголовки в «рамке», я делаю так:

repeat '-';
echo -e '\nHeader 1\t\tHeader 2\t\tHeader 3\t\t\t\tHeader 4';
repeat '-';

Уже неплохо. Символ \t означает = Табуляция. Ну а \n я думаю ты и так знаешь = Новая строка.

Гуд. Но функция всё равно не универсальная, хочется большего. Давай теперь передадим в функцию repeat количество повторов. В предыдущем скрипте у меня зашит харкод на 90 символов. Вуаля:

repeat() {
    range=$(seq $2)
    for i in $range; do echo -n "$1"; done
}

repeat '-' 20

Передаем в функцию 2 параметра, первый = какой символ loop’ить, второй = сколько будет повторов. В примере выше, символ «-» выведется 20 раз.

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

```shell # seq 5 1 2 3 4 5

seq -s : 5

1:2:3:4:5

С этим ок, разобрались. А что если воспользоваться <strong>printf</strong>? Давай попробуем.

С <strong>printf</strong> это реализуется намного проще, вот варианты:

```shell
printf -- '-%.0s' 1 2 3 4 5
printf -- '-%.0s' {1..20}

Разборка этой магии

Двойное тире означает «флаги командной строки». Поскольку мне нужно вывести «-», двойное тире указывает команде printf не пытаться анализировать то, что идет после параметров командной строки. ЧО?

Короче простым языком: если выводишь символ «-» через printf, то нужно двойное тире. Если выводишь к примеру символ «~» можно обойтись такой конструкцией:

printf '~%.0s' {1..20}; printf '\n'

Просто при выводе «-» printf думает что ты ему какой-то ключ хотел подсунуть и заорет: printf: -%: invalid option. В общем такая вот особенность. Ну либо всех обмануть и сделать так:

printf '%.0s-' {1..80}
Роман Шубин
Роман Шубин
CEO & CTO, Главред в «Цифровой улей»
Задать вопрос
Подобное можно реализовать с помощью внешних утилит таких как: awk/sed и т.п. Но чем больше ты усложняешь, тем тяжелее это дебажить. Это утверждение справедливо вообще для всего.

На закуску:

seq -s_ 20|tr -d '[:digit:]'

Надеюсь ты узнал что-то новое. Спасибо за внимание, ставь лайк, репости и приводи к нам своих коллег и друзей. Забашим!