Linux команда повторить строку n раз

Есть ли какая-либо встроенная команда Linux, которая позволяет выводить строку, которая в n раз больше входной строки??

17 ответов

Решение
adrian@Fourier:~$ printf 'HelloWorld\n%.0s' {1..5}
HelloWorld
HelloWorld
HelloWorld
HelloWorld
HelloWorld
adrian@Fourier:~$

Вот старомодный способ, который довольно портативный:

yes "HelloWorld" | head -n 10

Это более общепринятая версия ответа Адриана Петреску с использованием расширения скобки:

for i in {1..5}
do
    echo "HelloWorld"
done

Это эквивалентно:

for i in 1 2 3 4 5

Это более краткая и динамичная версия ответа Пики:

printf -v spaces '%*s' 10 ''; printf '%s\n' ${spaces// /ten}

Вы можете использовать трюк. Вывод пустой переменной ничего не печатает. Таким образом, вы можете написать:

echo word$wojek{1..100}

Если $wojek1 $wojek2... $wojek100 если переменные не существуют, ваше слово будет повторяться 100 раз, ничего больше.

Это может быть параметризовано и не требует временной переменной, FWIW:

printf "%${N}s" | sed 's/ /blah/g'

Или если $N размер массива bash:

echo ${ARR[@]/*/blah}

Несколько хороших способов уже упоминалось. Не могу забыть о старом добром seq хоть:

[john @ awesome] $ для меня в `seq 5`; сделать эхо "Привет" сделано
Привет
Привет
Привет
Привет
Привет

Повторение n раз, просто положить n-1 запятые между {}:

$ echo 'helloworld'{,,}
helloworld helloworld helloworld

Повторяет "helloworld" дважды после первого эха.

Никакой магии здесь:

seq 5 | awk '{print "Hello World"}'

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

adrian@Fourier:~$ n=5
adrian@Fourier:~$ for (( c=1; c<=n; c++)) ; do echo "HelloWorld" ; done
HelloWorld
HelloWorld
HelloWorld
HelloWorld
HelloWorld
adrian@Fourier:~$ 

Оболочка bash более мощная, чем думает большинство людей:)

Я испытал предупреждения о сломанной трубе с yes решение, так что вот еще одна хорошая альтернатива:

$ seq 4 | sed "c foo"
foo
foo
foo
foo
awk 'BEGIN {while (c++<4) printf "Hello"}'

Результат

Привет привет привет привет

Основываясь на том, на что намекал @pike

для каждого символа в строке

echo ${target//?/$replace}

Пример заголовка, подчеркнутого = персонажи

export heading='ABCDEF'; 
export replace='='; 
echo -e "${heading}\n${heading//?/$replace}"

будет выводить

ABCDEF
======

Кажется, это порт между Linux и OS X, и это делает меня счастливым.

NJoy!

Если вы находитесь на BSD, вы можете просто использовать seq,

$ seq -f "Hello, world" 5
Hello, world
Hello, world
Hello, world
Hello, world
Hello, world

Не совсем встроенный в Linux, но если у вас установлен Python..

python
>>>var = "string"
>>>var*n

Или в одной строке, как предложил комментатор:

python -c 'print "This is a test.\n" * 10'

Предполагая, что вы хотите что-то вроде Perl's x оператор, где вы автоматически не получаете новую строку между повторениями:

x() {
  # usage: x string num
  for i in $(seq 1 $2); do printf "%s" "$1"; done
  # print a newline only if the string does not end in a newline
  [[ "$1" == "${1%$'\n'}" ]] && echo ""
}

x Hi 10  # ==> HiHiHiHiHiHiHiHiHiHi

x $'Hello World!\n' 3

Я явно использовал for цикл, потому что вы не можете написать {1..$n} в bash: расширение скобок выполняется перед заменой переменных.

line="==========================="
line=${line:0:10}
${line//"="/"ten "}

выходы

ten ten ten ten ten ten ten ten ten ten

Попробуй это:

echo $(for i in $(seq 1 100); do printf "-"; done)

Создадим (сто тире):


В macOS и BSD вы можете использовать jot

      # Print 5 lines of `HelloWorld`
jot -b "HelloWorld" 5

# Print `HelloWorld` 5 times without newlines
jot -s "" -b "HelloWorld" 5

# Print `Hello` 5 times using a different separator which is `World` instead of newline
jot -s "World" -b "Hello" 5

В Linux вы можете установить athena-jot , чтобы получить его.

Например, это решение допускает любое количество повторений и является очень быстрым , хотя и не очень быстрым, как или настраиваемые собственные решения с SIMD и склейкой , которые могут достигать десятков ГБ данных в секунду.

С помощью можно печатать без новых строк вот так

      $ N=10000000
$ WORD=HelloWorld
$ yes $WORD | tr -d '\n' | head -c $(($N * ${#WORD}))

Тест:

Непосредственный цикл с оболочкой по понятным причинам медленный, поэтому не подходит для огромных значений. Вам всегда понадобятся внешние инструменты, такие какyes,sed,tr... для быстрого вывода. Трюк с расширением скобок{1..$N}также полностью терпит неудачу, когда$Nбольшой из-за слишком длинного списка аргументов , и использование замены строки переменной, как в ответе commonpike , приведет к тому, что оболочка скоро выйдет из строя из-за нехватки памяти или сработает OOM

Ниже приведены некоторые результаты при печати слова, следующего за новой строкой.

      $ time bash -c "echo $WORD\$_{1..$N} >/dev/null"

real    0m15.863s
user    0m15.189s
sys 0m0.646s

$ time bash -c "for i in {1..$N}; do echo $WORD; done >/dev/null"

real    0m42.728s
user    0m38.029s
sys 0m4.673s

$ time bash -c "for i in \$(seq $N); do echo $WORD; done >/dev/null"

real    0m43.073s
user    0m39.349s
sys 0m4.507s

Как видите, они очень медленные. Внешние инструменты взорвут их

      $ time bash -c "printf %${N}s | sed 's/ /$WORD\n/g' >/dev/null"

real    0m1.913s
user    0m1.847s
sys 0m0.071s

$ time jot -b $WORD $N >/dev/null

real    0m1.262s
user    0m1.255s
sys 0m0.005s

$ time yes $WORD | head -n $N >/dev/null

real    0m0.912s
user    0m0.903s
sys 0m0.031s

$ time gyes $WORD | head -n $N >/dev/null

real    0m0.930s
user    0m0.947s
sys 0m0.090s

$ time yes $WORD | ghead -n $N >/dev/null

real    0m0.246s
user    0m0.138s
sys 0m0.213s

$ time gyes $WORD | ghead -n $N >/dev/null

real    0m0.258s
user    0m0.175s
sys 0m0.242s

Я провожу эти тесты на macOS, и в последних четырех тестах вы можете увидеть, насколько ужасны инструменты BSD по сравнению с инструментами GNU (с префиксомgиз-за конфликта имен со стандартными инструментами BSD), хотя они все равно намного быстрее, чем оболочка

Вышеупомянутые случаи относятся к завершающей новой строке, а при печати без новых строк инструменты GNU также оставляют инструменты BSD в пыли.

      $ time yes $WORD | tr -d '\n' | ghead -c 300M >/dev/null

real    0m26.763s
user    0m26.857s
sys 0m0.381s

$ time gyes $WORD | tr -d '\n' | ghead -c 300M >/dev/null

real    0m27.972s
user    0m28.142s
sys 0m0.598s

$ time yes $WORD | gtr -d '\n' | ghead -c 300M >/dev/null

real    0m1.353s
user    0m0.609s
sys 0m0.981s

$ time gyes $WORD | gtr -d '\n' | ghead -c 300M >/dev/null

real    0m0.980s
user    0m0.785s
sys 0m1.095s
Другие вопросы по тегам