Обновленный ответ для более общего решения. см. также мой другой ответ ниже, используя только расширение скобки и pritnf
.
$ str='Hello World!'
$ sed -r ':loop; s/ (=*):$/\1=:/; t loop' <<< "$(printf '%-20s:\n' "$str" )"
Hello World!========:
Как это устроено?
это (=*):$/
захватывает один пробел, один или более =
, за которым следует двоеточие :
в конце ввода; мы делаем набор =
как групповое совпадение и \1
будем его обратной ссылкой.
С помощью :loop
мы определили названную метку loop
и вместе с t loop
ней перейдем к этой метке, когда a s/ (=*):$/\1=:/
выполнит успешную замену;
В замене с помощью \1=:
, он всегда будет увеличивать число =
s и возвращать само двоеточие до конца строки.
дает
${#string}
длина значения$string
и${filler:${#string}}
подстрока$filler
от смещения${#string}
вперед.Общая ширина вывода будет равна максимальной ширине
$filler
или$string
.Строка-заполнитель может в системах
jot
, которые создаются динамически с использованием(по 16
=
в строке). Системы GNU могут использоватьseq
:Другие системы могут использовать Perl или какой-либо другой более быстрый способ динамического создания строки.
источник
printf
для генерации фильтра, который почти доступен во всех системах, и расширение скобок с подобными оболочкамиbash/szh
?printf
расширением + скобкаbash
?где
%.20s
формат усечения строкиисточник
Один из способов сделать это:
источник
====================\rhello world
, что может быть проблемой, если оператору нужно сохранить это, а не просто напечатать его на экране.echo -e '=================\rHello World!!'
, но имеет ту же проблему, на которую указал @terdon.echo
поддерживает-e
.printf
почти всегда лучше, чемecho
по многим причинам.Подход Perl:
Или лучше @SatoKatsura отметил в комментариях:
Если вам нужно поддерживать многобайтовые символы UTF, используйте:
Та же идея в оболочке:
источник
perl -le '$k = "hello world!!"; print $k, "=" x (20-length $k), "\n"'
. Однако это (и все другие решения, опубликованные до сих пор) ломаются, если задействованы многобайтовые символы.perl6
может быть способ сделать это правильно, даже с многобайтовыми символами. Но с другой стороныperl6
это раздражает во многих отношениях.PERL_UNICODE='AS'
. Например:printf '%s' nóóös | perl -nle 'print length($_)'
печатает 8 («неправильно»), аprintf '%s' nóóös | PERL_UNICODE='AS' perl -nle 'print length($_)'
печатает 5 («правильно»).Другой способ заключается в использовании только
printf
команды и генерировать шаблон символов дополнени сначалаShell Brace Expansion
(Вы можете положить конец с номером ≥ Форматирование области вы хотите напечатать в{1..end}
) и получить только каждый первый символ этого ,%.1s
который является=
s , а затем напечатать длину только первые 20 символов область этого%.20s
. Это своего рода лучший способ иметь повторяющиеся символы / слова вместо их дублирования.Пояснения:
Обычно, как Brace Expansion , оболочка расширяется
{1..20}
следующим образом, если мы печатаем их.Таким образом, при добавлении к нему знака равенства
={1..20}
оболочка будет расширяться следующим образом.И
printf '%.1s'
это означаетprintf '%WIDE.LENGTH'
, что мы печатаем только одну ДЛИНУ из тех , что указаны выше, по умолчанию1
WIDE . так приведут=
только s и 20 раз повторились.Теперь, когда
printf '%.20s:\n'
мы печатаем только длину 20,$str
а если длина$str
<20, остальная часть будет=
заполняться из сгенерированных s вместо пробелов.источник