2016-05-18 5 views
7

printf Используя, можно напечатать символ, несколько раз:Как использовать printf для печати символа несколько раз?

В awk я знаю, что я могу сделать something like:

$ awk 'BEGIN {while (i++ < 5) printf "-"}' 
----- 

Но мне интересно, если awk's printf позволяет это, а также.

Я просмотрел страницу printf modifiers, но не смог найти. В общем, что Printf от Bash делает это расширение {1..5} и печать - для каждого параметра он получает, так что это равносильно тому,

$ printf "%0.s-" hello how are you 42 
----- 

Однако, мне не хватает знаний о том, как имитировать это поведение с Printf AWK, если оно возможно, потому что это не поможет:

$ awk 'BEGIN {printf "%0.s-", 1 2 3 4 5}' 
- 
+1

Мммм, Perl может сделать это слишком ... 'Perl -e«печать «5'x60" ' :-) –

+0

@MarkSetchell 'AWK 'не так уж и умный:/Ни« печатать »« * 3 », ни« печатать »работу« x 3 ». – fedorqui

ответ

6

Я не считаю, что это возможно с Printf AWK, поскольку there is also no way to do this just with printf in C and C++.

С awk, я думаю, наиболее разумным вариантом является использование цикла, как и у вас. Если по каким-то причинам производительности является жизненно важным и AWK создает узкое место, следующее будет ускорить:

awk 'BEGIN {s=sprintf("%5s","");gsub(/ /,"-",s);print s}' 

Эта команда будет работать быстрее логарифмически [1] Хотя, это не вызовет заметной разницы в если вы планируете многократно печатать символ. (Печать персонажу 1000000 раз будет около 13x быстрее.)

Кроме того, если вы хотите одну гильзу и используют Gawk, несмотря на то, что это самый медленный из связки:

gawk 'BEGIN {print gensub(/ /,"-","g",sprintf("%5s",""));}' 

 

[1] Хотя команда sprintf/gsub всегда должна быть быстрее, чем использование цикла, я не уверен, что все версии awk будут вести себя так же, как мои. Я также не понимаю, почему команда awk while-loop будет иметь временную сложность O (n * log (n)), но она работает в моей системе.

+2

Блестящий! Не могли бы вы рассказать о том, как вы узнали о сложности времени? I timed 'awk 'BEGIN {while (i ++ <1000000) printf" - "}'' и 'awk 'BEGIN {s = sprintf ("% 1000000s "," "); gsub (/ /," - ", s) ; print s} '', и разница была 0,102s против 0.115s. – fedorqui

+1

Абсолютно.Я написал функцию bash для сравнения четырех различных команд awk: while-loop one, 'gsub', gensub, и элемента управления, который только печатал одну тире. Эта функция проверяет все команды на самые разные длины входов и повторений, вычитая время фиктивного из других трех. Из этого я обнаружил, что gensub один был намного медленнее остальных, поэтому я сосредоточился на vs gsub. Затем я взял свои данные и поиграл с ним с помощью wolframalpha, пользовательских математических функций и листа google, что привело меня к этим значениям большого О. –

+0

[Вот один из листов google] (https://docs.google.com/spreadsheets/d/1P8neMgoyJf34uoV1JtQ3hiEZuL0LWnl55z0zTXjwJ-E/edit?usp=sharing), если вам интересно. Это единственная часть процесса, который я все еще оставил –

1

Я знаю, что это старый, но модификатор ширины может использоваться, например.

л = some_value

печати gensub (/ /, "-", "г", Sprintf ("% * s", л ""))

будет печатать переменное число - в зависимости от величины л

Это GNU Awk 3.1.8