Повторно печатайте символ в bash

Есть ли способ печатать один и тот же символ повторно в bash, так же, как вы можете использовать эту конструкцию для этого в python:

print('%' * 3)

дает

%%%

Ответ 1

конечно, просто используйте printf и немного bash манипуляции с строкой

$ s=$(printf "%-30s" "*")
$ echo "${s// /*}"
******************************

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

printf_new() {
 str=$1
 num=$2
 v=$(printf "%-${num}s" "$str")
 echo "${v// /*}"
}

Тестирование:

$ printf_new "*" 20
********************
$ printf_new "*" 10
**********
$ printf_new "%" 10
%%%%%%%%%%

Ответ 2

На самом деле это однострочный, который может сделать это:

    printf "%0.s-" {1..10}

печатает

    ----------

Здесь пробой аргументов, переданных в printf:

  • % s - указывает строку любой длины
  • % 0s - Указывает строку нулевой длины, но если аргумент длиннее, он распечатает все это.
  • % 0.s - Это то же самое, что и выше, но период сообщает printf обрезать строку, если она длиннее указанной длины, которая равна нулю
  • {1..10} - Это расширение скобки, которое фактически передает аргументы "1 2 3 4 5 6 7 8 9 10"
  • "-" - Это дополнительный символ, предоставляемый printf, это может быть что угодно (для "%" вы должны избегать его с другим "%" сначала, то есть "%%" )
  • И, наконец, поведение по умолчанию для printf, если вы даете ему больше аргументов, чем указано в строке формата, нужно выполнить обратный возврат к началу строки формата и запустить его снова.

Конечным результатом здесь является то, что вы сообщаете printf, что вы хотите, чтобы он печатал строку нулевой длины без дополнительных символов, если предоставленная строка длиннее нуля. Затем после этой строки нулевой длины напечатайте символ "-" (или любой другой набор символов). Затем вы предоставляете ему 10 аргументов, поэтому он печатает 10 строк нулевой длины, каждый из которых имеет "-".

Это однострочный шрифт, который печатает любое количество повторяющихся символов!

Edit:

Кстати, если вы хотите напечатать символы $variable, вам просто нужно немного изменить аргумент, чтобы использовать seq, а не расширять фигуру следующим образом:

    printf '%0.s-' $(seq 1 $variable)

Вместо этого передаются аргументы "1 2 3 4... $variable" до printf, печатая точно $variable экземпляры "-"

Ответ 3

Текущий принятый ответ на этот вопрос (ghostdog74) предоставляет метод, который выполняется чрезвычайно медленно даже для умеренно большого количества символов. Ответ на верхний голос (CaffeineConnoisseur) лучше, но все еще довольно медленный.

Вот что в моих тестах выполнило быстрее всех (даже быстрее, чем версия python):

perl -E "print '*' x 1000"

На втором месте была команда python:

python -c "print('*' * 1000)"

Если ни perl, ни python не доступны, это будет третьим:

head -c 1000 /dev/zero | tr '\0' '*'

И на четвертом месте находится встроенный bash printf с tr:

printf '%*s' 1000 | tr ' ' '*'

И вот один (из CaffeineConnoisseur ответ), который на пятом месте в скорости для большого количества повторяющихся символов, но может быть быстрее для небольших чисел (из-за используя только встроенный bash, а не создавая внешний процесс):

printf '%.s*' {1..1000}

Ответ 4

Мне это нравится:

echo $(yes % | head -n3)

Вам может не понравиться следующее:

for ((i=0; i<3; i++)){
   echo -ne "%"
}

Вам может понравиться следующее:

s=$( printf "%3s" ); echo " ${s// /%}"

Источник: http://dbaspot.com/shell/357767-bash-fast-way-repeat-string.html

Существует также эта форма, но не очень полезная:

echo %{,,}

Ответ 5

Это уродливо, но вы можете сделать это вот так:

$ for a in `seq 5`; do echo -n %; done
%%%%%

Конечно, seq - внешняя программа (которую вы, вероятно, имеете).

Ответ 6

Другой:

char='%'
count=5
result=$( printf "%${count}s" ' ' )
echo -e ${result// /$char}

Ответ 7

  • Можно получить любое число нулевого символа (\0) из /dev/zero. Осталось только сделать это

    head -c 20 /dev/zero |tr '\0' '+'
    

    Обратите внимание, что head и tr являются внешними командами. Так что он будет вызываться в отдельном процессе.

  • "Оптимизировать" это решение можно с помощью кэширования строк.

    CACHE="$(head -c 1000 /dev/zero |tr '\0' '+')"
    echo "${CACHE:0:10}"
    echo "${CACHE:0:100}"
    echo "${CACHE:0:300}"
    

    В выражении echo есть только bash встроенные модули. Таким образом, мы можем использовать его в цикле.

Ответ 8

#!/usr/bin/awk -f
BEGIN {
  while (c++ < 3) printf "%"
}

Результат

%%%

Ответ 9

Вот самый простой способ сделать это

seq -s % 4|tr -d '[:digit:]'

Обратите внимание, что в созданной последовательности будет только 3 '%'.