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 कॉलम चौड़ा है ( इनपुट में सबसे चौड़ी लाइन की डिस्प्ले चौड़ाई की रिपोर्ट करने के लिए -LGNU 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"