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

71

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

Получить бесплатно
источник
1
Под «встроенной командой linux» я предполагаю, что вы имеете в виду команду оболочки, а поскольку вы не упоминаете, какую оболочку вы используете, я предполагаю, что это bash. Вы можете проверить это, набрав «echo $ SHELL» в командной строке, и вы должны получить что-то похожее на «/ bin / bash». Если вы этого не сделаете, вы должны отредактировать свой ответ, чтобы указать, что он показывает. Приветствия :)
Адриан Петреску
7
Я пометил вопрос с "Баш". Я думал, что этого было бы достаточно.
GetFree

Ответы:

75
adrian@Fourier:~$ printf 'HelloWorld\n%.0s' {1..5}
HelloWorld
HelloWorld
HelloWorld
HelloWorld
HelloWorld
adrian@Fourier:~$
Адриан Петреску
источник
3
Не могли бы вы объяснить, как это работает? Я понимаю команду printf, поскольку она такая же, как в C / C ++. Но я не понимаю, как {1..5} расширяется и как это работает в сочетании с частью "% .0s".
GetFree
4
Это что-то вроде хака :) Попробуйте запустить "printf 'HelloWorld% d \ n' 1 2 3 4 5", и он, вероятно, щелкнет для вас. Флаг% .0s предназначен для того, чтобы ничего не делать, просто быть там, чтобы подобрать аргументы. Затем, если bash получит больше аргументов, чем имеет спецификатор формата, он просто распечатает несколько копий, захватив столько, сколько ему нужно. Таким образом, вы получите эффект. Вывод "printf 'HelloWorld% d% d \ n' 1 2 3 4 5 6", вероятно, делает его еще более понятным. Надеюсь это поможет!
Адриан Петреску
Понимаю. Это специфическое поведение printf, которое позволяет повторение
GetFree
1
(Следует отметить, что с чисто теоретической точки зрения это, вероятно, самое быстрое решение, поскольку оно использует один примитив оболочки, а не какие-либо внешние процессы. Однако в действительности, давайте посмотрим правде в глаза, производительность сценариев bash на самом деле не имеет значения: )
Адриан Петреску
1
Что является специфическим для printfтом , что он будет повторно применить лишние аргументы в строку формата, «перекручивание» бесплатно. Под «избытком» я подразумеваю, что аргументов больше, чем %заполнителей.
Деннис Уильямсон
69

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

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}
Деннис Уильямсон
источник
Как избавиться от новых строк при использовании команды yes?
GetFree
3
Один из способов состоит в том, чтобы передать его по каналу, sed -n 'H;${x;s/\n//gp}'а sed -n ':t;${s/\n//gp};N;bt'другой - echo $(yes "HelloWorld" | head -n 10)добавить пробел между каждой копией строки. Еще один способ состоит в том, чтобы пройти через него, tr -d '\n'что также устраняет последний перевод строки.
Деннис Уильямсон
2
Это как Haskell в оболочке bash: Hashell?
wchargin
4
Решение "да" довольно опрятно
piggybox
yesРешение было именно то , что мне было нужно, так как я хотел , чтобы дублировать команду (выход которого колеблется). Таким образом:yes "$(my-command)" | head -n 2
Арнсхолт
14

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

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

Или, если $Nэто размер массива bash:

echo ${ARR[@]/*/blah}
twifkak
источник
3
Это самое короткое решение POSIX 7, которое я видел до сих пор seq, yesи оно {1..5}не является POSIX 7.
Ciro Santilli,
Вы не должны смешивать данные в printfспецификаторе формата. Что если данные содержат строки формата? Это правильный способ динамически определять «точность» (длину): printf '%*s' "$N"- сделать привычкой заключать строку формата в одинарные кавычки, чтобы предотвратить расширение переменной там.
Деннис Уильямсон
13

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

[john @ awesome] $ для меня в `seq 5`; сделать эхо "Привет" сделано
Здравствуй
Здравствуй
Здравствуй
Здравствуй
Здравствуй
Джон Т
источник
Этот на самом деле уважает ноль, рассматривая его как ноль! ( {i..j}Трюк никогда не возвращает пустой диапазон.)
JellicleCat
10

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

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

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

Адриан Петреску
источник
Это получает мой голос, так как это полностью внутренняя оболочка; разветвление не требуется.
ESM
2
На какую разветвленность вы ссылаетесь? Оригинальный ответ не требует ничего. Выводом «type printf» является «printf - встроенная оболочка», и поэтому он выполняется в исходном процессе bash.
CodeGnome
Это единственный до сих пор ( yes, printf, for i in {1..5}) , что если nравен нулю, то возвращается пустая строка , не существует состояние 1. Также в связи с математической нотации для сравнения, легко компенсировали на 1 (например , путем изменения <=в <)
Мехрад Махмудян
10

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

echo word$wojek{1..100}

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

Войцех Вага
источник
1
Это уродливый, уродливый хак, и все же я не могу не любить его и использовать его.
16807
Любить это! Возможно, использование $_вместо того, чтобы $wojekсделать намерение более ясным.
Михай Тодор
7

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

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

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

кэв
источник
5
Хорошо, но что, если я хочу получить nиз переменной?
GetFree
1
это добавляет дополнительное пространство после каждого «helloworld»
PADYMKO
кажется, что это не позволяет вам также вводить строки в строку (т.е. получать helloworld на их собственные строки)
TankorSmash
5
awk 'BEGIN {while (c++<4) printf "Hello"}'

Результат

Привет привет привет привет
Стивен Пенни
источник
Используйте это без awk: while ((c ++ <5)); сделать printf 'привет'; сделано
эдс
4

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

$ seq 4 | sed "c foo"
foo
foo
foo
foo
n.caillou
источник
3

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

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

echo ${target//?/$replace}

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

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

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

ABCDEF
======

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

NJoy!

nickl-
источник
3

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

$ seq -f "Hello, world" 5
Hello, world
Hello, world
Hello, world
Hello, world
Hello, world
Qix
источник
1
In seq (GNU coreutils) 8.25, это дает seq: format 'Hello, world' has no % directive, заставляя директиву форматирования присутствовать. GNU coreutils используются, например, во многих дистрибутивах Linux и Cygwin. Включая информацию здесь для тех, кому не хватает информации, что она работает только в BSD seq.
Палек
2
line="==========================="
line=${line:0:10}
${line//"="/"ten "}

выходы

ten ten ten ten ten ten ten ten ten ten
commonpike
источник
Может быть, более подробный пример: Declare C = '-----'; с = $ {с // $ {с: 0: 1} / $ с}; echo $ c # Prints "-" 25 раз.
Стивен Недзельски,
2

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

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: раскрытие скобки выполняется до подстановки переменной.

Гленн Джекман
источник
2

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

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

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

python -c 'print "This is a test.\n" * 10'
eqzx
источник
4
Не очень полезно, так как это не может быть легко интегрировано в скрипты оболочки и т. Д. И так как в самой оболочке есть около миллиарда способов сделать это, я не вижу особой причины для того, чтобы использовать для этого большие средства (например, Python). ,
Адриан Петреску
7
Я согласен с вашим вторым замечанием, но не с первого взгляда ... его легко интегрировать в скрипт оболочки: python -c 'print "Это тест. \ N" * 10'
larsks
Мне нравится удобочитаемость этого решения, достаточно веская причина для меня. ;)
Элиас
2

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

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

brablc
источник
1

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

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

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


Алле Альдин
источник