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" дважды после первого эха.
Возможно, другой способ, который является более общим и полезным для вас:
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