POSIX की आवश्यकता printf
है %-20s
के मामले में उन 20 गिनती करने के लिए बाइट नहीं वर्ण है कि भले ही थोड़ा समझ में आता है के रूप में printf
मुद्रित करने के लिए है पाठ , प्रारूपित (चर्चा देखने के ऑस्टिन समूह में (इसे POSIX) और bash
मेलिंग सूची)।
printf
की निर्मित bash
और अधिकांश अन्य POSIX गोले कि सम्मान करते हैं।
zsh
उस मूर्खतापूर्ण आवश्यकता को अनदेखा करता है (यहां तक कि sh
अनुकरण में भी ) तो वह printf
काम करता है जैसा कि आप वहां चाहते हैं। के printf
अंतर्निहित के लिए एक ही fish
(एक POSIX की तरह नहीं खोल)।
ü
चरित्र (U + 00FC), जब UTF-8 में एन्कोड दो बाइट्स (0xc3 और 0xbc) है, जो विसंगति बताते हैं से बना है।
$ printf %s 'Früchte und Gemüse' | wc -mcL
18 20 18
वह तार 18 अक्षरों से बना है, 18 कॉलम चौड़ा है ( इनपुट में सबसे चौड़ी लाइन की डिस्प्ले चौड़ाई की रिपोर्ट करने के लिए -L
GNU wc
एक्सटेंशन है) लेकिन 20 बाइट्स पर एन्कोडेड है।
में zsh
या fish
, पाठ ठीक से संरेखित किया जाएगा।
अब, ऐसे अक्षर भी हैं, जिनमें 0-चौड़ाई है (जैसे U + 0308 जैसे वर्णों को मिलाना, तिर्यकदृष्टि को जोड़ना) या कई एशियाई लिपियों की तरह डबल-चौड़ाई है (टैब जैसे नियंत्रण वर्णों का उल्लेख नहीं करना) और यहां तक zsh
कि संरेखित नहीं करेंगे वे ठीक से।
उदाहरण में zsh
:
$ printf '%3s|\n' u ü $'u\u308' $'\u1100'
u|
ü|
ü|
ᄀ|
इन bash
:
$ printf '%3s|\n' u ü $'u\u308' $'\u1100'
u|
ü|
ü|
ᄀ|
ksh93
प्रदर्शन चौड़ाई के %Ls
संदर्भ में चौड़ाई की गणना करने के लिए एक प्रारूप विनिर्देश है ।
$ printf '%3Ls|\n' u ü $'u\u308' $'\u1100'
u|
ü|
ü|
ᄀ|
यह अभी भी काम नहीं करता है अगर पाठ में TAB जैसे नियंत्रण वर्ण हैं (यह कैसे हो सकता है? यह printf
जानना होगा कि आउटपुट डिवाइस में टैब स्टॉप के अलावा कितनी दूर हैं और यह किस स्थिति में मुद्रण करना शुरू करता है)। यह बैकस्पेस वर्णों के साथ दुर्घटना के द्वारा काम करता है (जैसे roff
आउटपुट में जहां X
(बोल्ड X
) के रूप में लिखा गया है X\bX
) हालांकि ksh93
सभी नियंत्रण वर्णों की चौड़ाई मानता है -1
।
अन्य विकल्पों के रूप में, आप कोशिश कर सकते हैं:
printf '%s\t|\n' u ü $'u\u308' $'\u1100' | expand -t3
यह कुछ expand
कार्यान्वयन के साथ काम करता है (जीएनयू के हालांकि नहीं)।
GNU सिस्टम पर, आप GNU का उपयोग कर सकते हैं awk
जिनकी printf
गिनती वर्णों में होती है (बाइट्स नहीं, प्रदर्शन-चौड़ाई नहीं, इसलिए अभी भी 0-चौड़ाई या 2-चौड़ाई वाले वर्णों के लिए ठीक नहीं है, लेकिन आपके नमूने के लिए ठीक है):
gawk 'BEGIN {for (i = 1; i < ARGC; i++) printf "%-3s|\n", ARGV[i]}
' u ü $'u\u308' $'\u1100'
यदि आउटपुट किसी टर्मिनल पर जाता है, तो आप कर्सर पोजिशनिंग एस्केप सीक्वेंस का भी उपयोग कर सकते हैं। पसंद:
forward21=$(tput cuf 21)
printf '%s\r%s%s\n' \
"Früchte und Gemüse" "$forward21" "foo" \
"Milchprodukte" "$forward21" "bar" \
"12345678901234567890" "$forward21" "baz"