POSIX đòi hỏi printf 's %-20sđể đếm những 20 về byte không nhân vật mặc dù tạo ra rất ít cảm giác như printflà in văn bản , định dạng (xem thảo luận tại Tập đoàn Austin (POSIX) và bashmailing list).
Việc xây printfdựng bashvà hầu hết các vỏ POSIX khác tôn vinh điều đó.
zshbỏ qua yêu cầu ngớ ngẩn đó (ngay cả trong shthi đua) để printfhoạt động như bạn mong đợi ở đó. Tương tự đối với phần printfdựng sẵn của fish(không phải là vỏ giống POSIX).
Ký ütự (U + 00FC), khi được mã hóa bằng UTF-8 được tạo thành từ hai byte (0xc3 và 0xbc), giải thích sự khác biệt.
$ printf %s 'Früchte und Gemüse' | wc -mcL
18 20 18
Chuỗi đó được tạo thành từ 18 ký tự, rộng 18 cột ( -Llà wcphần mở rộng GNU để báo cáo độ rộng hiển thị của dòng rộng nhất trong đầu vào) nhưng được mã hóa trên 20 byte.
Trong zshhoặc fish, văn bản sẽ được căn chỉnh chính xác.
Giờ đây, cũng có những ký tự có độ rộng 0 (như kết hợp các ký tự như U + 0308, diaresis kết hợp) hoặc có độ rộng gấp đôi như trong nhiều tập lệnh Asiatic (không đề cập đến các ký tự điều khiển như Tab) và thậm chí zshsẽ không căn chỉnh những cái đó đúng
Ví dụ, trong zsh:
$ printf '%3s|\n' u ü $'u\u308' $'\u1100'
u|
ü|
ü|
ᄀ|
Trong bash:
$ printf '%3s|\n' u ü $'u\u308' $'\u1100'
u|
ü|
ü|
ᄀ|
ksh93có một %Lsđặc điểm kỹ thuật định dạng để đếm chiều rộng theo chiều rộng màn hình .
$ printf '%3Ls|\n' u ü $'u\u308' $'\u1100'
u|
ü|
ü|
ᄀ|
Điều đó vẫn không hoạt động nếu văn bản chứa các ký tự điều khiển như TAB (làm thế nào nó printfcó thể phải biết các điểm dừng cách xa nhau trong thiết bị đầu ra và vị trí bắt đầu in ở vị trí nào). Nó hoạt động một cách tình cờ với các ký tự backspace (như trong roffđầu ra trong đó X(in đậm X) được viết là X\bX) mặc dù ksh93coi tất cả các ký tự điều khiển là có chiều rộng -1.
Như các tùy chọn khác, bạn có thể thử:
printf '%s\t|\n' u ü $'u\u308' $'\u1100' | expand -t3
Điều đó hoạt động với một số expandtriển khai (mặc dù không phải GNU).
Trên các hệ thống GNU, bạn có thể sử dụng GNU awkcó printfsố đếm bằng ký tự (không phải byte, không phải chiều rộng hiển thị, do đó vẫn không ổn đối với các ký tự 0 chiều rộng hoặc 2 chiều rộng, nhưng OK cho mẫu của bạn):
gawk 'BEGIN {for (i = 1; i < ARGC; i++) printf "%-3s|\n", ARGV[i]}
' u ü $'u\u308' $'\u1100'
Nếu đầu ra đi đến một thiết bị đầu cuối, bạn cũng có thể sử dụng các chuỗi thoát định vị con trỏ. Như:
forward21=$(tput cuf 21)
printf '%s\r%s%s\n' \
"Früchte und Gemüse" "$forward21" "foo" \
"Milchprodukte" "$forward21" "bar" \
"12345678901234567890" "$forward21" "baz"