Хеллоу! Попался мне вчера чей-то очередной 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 5seq -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}
На закуску:
seq -s_ 20|tr -d '[:digit:]'
Надеюсь ты узнал что-то новое. Спасибо за внимание, ставь лайк, репости и приводи к нам своих коллег и друзей. Забашим!








Комментарии