2016-05-18 25 views
7

Sử dụng printf, người ta có thể in một nhân vật nhiều lần:Làm thế nào để sử dụng printf để in một nhân vật nhiều lần?

Trong awk Tôi biết rằng tôi có thể làm something like:

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

Nhưng tôi tự hỏi, nếu awk's printf phép này là tốt.

Tôi đã xem qua trang printf modifiers nhưng không thể tìm thấy cách thực hiện. Tất cả trong tất cả, những gì printf từ Bash làm là để mở rộng {1..5} và in - cho mỗi tham số nó được, vì vậy nó tương đương với nói

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

Tuy nhiên, tôi thiếu kiến ​​thức về làm thế nào để bắt chước hành vi này với printf awk, nếu có thể, bởi vì đây không:

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

Mmmm, Perl có thể làm điều đó quá ... 'perl -e "in '5'x60" ':-) –

+0

@MarkSetchell' awk 'không phải là thông minh:/Không phải' in 'a' * 3' cũng không phải 'in' một tác phẩm "x 3'. – fedorqui

Trả lời

6

tôi không tin rằng điều này là có thể với printf awk, như there is also no way to do this just with printf in C and C++.

Với awk, tôi nghĩ tùy chọn hợp lý nhất là sử dụng vòng lặp giống như bạn có. Nếu vì lý do hiệu suất là rất quan trọng và awk đang tạo ra một nút cổ chai, sau đây sẽ điều tốc độ lên:

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

Lệnh này sẽ chạy nhanh hơn loga [1] Mặc dù, nó sẽ không gây ra một sự khác biệt đáng chú ý trong hiệu suất trừ khi bạn đang lên kế hoạch in một nhân vật nhiều lần. (In một nhân vật 1.000.000 lần sẽ vào khoảng 13x nhanh hơn.)

Ngoài ra, nếu bạn muốn có một one-liner và đang sử dụng gawk, mặc dù đó là chậm nhất của bunch:

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

 

[1] Trong khi lệnh sprintf/gsub phải luôn nhanh hơn sử dụng vòng lặp, tôi không chắc liệu tất cả các phiên bản của awk sẽ hoạt động giống như của tôi hay không. Tôi cũng không hiểu tại sao lệnh awk while-loop sẽ có độ phức tạp về thời gian của O (n * log (n)), nhưng nó có trên hệ thống của tôi.

+2

Brilliant! Bạn có thể chia sẻ thông tin chi tiết về cách bạn biết thời gian phức tạp không? Tôi đã hẹn giờ 'awk 'BEGIN {trong khi (i ++ <1000000) printf" - "}'' và 'awk 'BEGIN {s = sprintf ("% 1000000s "," "); gsub (/ /," - ", s) ; in s} ''và sự khác biệt là 0.102s so với 0.115s. – fedorqui

+1

Tuyệt đối.Tôi đã viết một hàm bash để chuẩn bốn lệnh awk khác nhau: một trong những vòng lặp, một 'gsub' một,' gensub' một, và một điều khiển mà chỉ in một dấu gạch ngang đơn. Chức năng này đã kiểm tra tất cả các lệnh chống lại nhiều độ dài đầu vào và lặp lại, trừ đi thời gian giả từ ba điểm còn lại. Từ điều này, tôi thấy rằng gensub chậm hơn nhiều so với phần còn lại, vì vậy tôi chỉ tập trung vào trong khi so với gsub. Sau đó tôi lấy dữ liệu của tôi và chơi xung quanh với nó với wolframalpha, chức năng toán học tùy chỉnh và một tờ google, dẫn tôi đến những giá trị lớn-O. –

+0

[Đây là một trong những trang tính google] (https://docs.google.com/spreadsheets/d/1P8neMgoyJf34uoV1JtQ3hiEZuL0LWnl55z0zTXjwJ-E/edit?usp=sharing), trong trường hợp bạn tò mò. Đó là phần duy nhất của quá trình tôi vẫn còn lại –

1

Tôi biết điều này cũ nhưng có thể sử dụng công cụ sửa đổi chiều rộng, ví dụ:

l = some_value

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

sẽ in một số biến của - tùy thuộc vào giá trị của l

Đây là GNU aWK 3.1.8

Các vấn đề liên quan