2016-05-18 37 views
7

Utilizzando printf, si può stampare un personaggio più volte:Come utilizzare printf per stampare un carattere più volte?

In awk so che posso fare something like:

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

ma mi chiedo se awk's printf permette anche questo.

Sono passato attraverso la pagina printf modifiers ma non ho trovato il modo. Tutto sommato, quello che il printf da Bash fa è quello di espandere {1..5} e stampare un - per ogni parametro si ottiene, in modo che equivale a dire

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

Tuttavia, mi manca la conoscenza su come imitare questo comportamento con printf di awk, se è possibile, perché questo non funziona:

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

Mmmm, Perl puo 'farlo ... 'perl -e "print '5'x60" ':-) –

+0

@MarkSetchell' awk 'non è così intelligente:/Né' stampa "a" * 3' né "stampa" a "x 3". – fedorqui

risposta

6

non credo che questo è possibile con printf di awk, come there is also no way to do this just with printf in C and C++.

Con awk, penso che l'opzione più ragionevole stia usando un loop come quello che hai. Se per qualche motivo le prestazioni è di vitale importanza e awk sta creando un collo di bottiglia, il seguente sarà accelerare le cose:

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

Questo comando verrà eseguito in modo logaritmico più veloce [1] Anche se, non sarà causare una notevole differenza nella prestazioni a meno che tu non stia pianificando di stampare un personaggio molte volte. (Stampa di un personaggio 1.000.000 volte sarà di circa 13x più veloce.)

Inoltre, se si desidera una battuta e si utilizza gawk, anche se è il più lento del gruppo:

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

 

[1] Mentre il comando sprintf/gsub deve essere sempre più veloce dell'utilizzo di un ciclo, non sono sicuro che tutte le versioni di awk si comportino come le mie. Inoltre non capisco perché il comando awk del ciclo while abbia una complessità temporale di O (n * log (n)), ma lo fa sul mio sistema.

+2

Brillante! Potresti condividere l'intuizione su come hai conosciuto la complessità del tempo? Ho temporizzato "awk" BEGIN {while (i ++ <1000000) printf "-"} "e" awk "BEGIN {s = sprintf ("% 1000000s "," "); gsub (/ /," - ", s) ; print s} '' e la differenza era 0.102s contro 0.115s. – fedorqui

+1

Assolutamente.Ho scritto una funzione bash per confrontare quattro diversi comandi awk: quello while-loop, quello 'gsub', quello' gensub' e un controllo che stampava solo un singolo trattino. Questa funzione ha testato tutti i comandi su un'ampia varietà di lunghezze di input e ripetizioni, sottraendo il tempo fittizio dagli altri tre. Da questo, ho trovato che il gensub era molto più lento del resto, quindi mi sono concentrato su mentre vs gsub. Ho quindi preso i miei dati e giocato con esso con wolframalpha, funzioni matematiche personalizzate e un foglio google, portandomi a quei valori big-O. –

+0

[Ecco uno dei fogli di google] (https://docs.google.com/spreadsheets/d/1P8neMgoyJf34uoV1JtQ3hiEZuL0LWnl55z0zTXjwJ-E/edit?usp=sharing), nel caso siate curiosi. È l'unica parte del processo che mi rimane ancora –

1

So che questo è vecchio ma il modificatore di larghezza può essere utilizzato per es.

l = some_value

gensub stampa (/ /, "-", "g", sprintf ("% * s", l, ""))

stamperà un numero variabile di - a seconda del valore di l

Questo è stato GNU awk 3.1.8