आप बाहरी उपयोगिताओं को कॉल कर सकते हैं (अन्य उत्तर देखें), लेकिन वे आपकी स्क्रिप्ट को धीमा कर देंगे, और प्लंबिंग अधिकार प्राप्त करना कठिन है।
Zsh
Zsh में, आप ${#$(readlink -f /etc/fstab)}
कमांड प्रतिस्थापन की लंबाई प्राप्त करने के लिए लिख सकते हैं । ध्यान दें कि यह कमांड आउटपुट की लंबाई नहीं है, यह किसी भी नई ट्राइलिंग के बिना आउटपुट की लंबाई है।
यदि आप आउटपुट की सटीक लंबाई चाहते हैं, तो अंत में एक अतिरिक्त नॉन-न्यूलाइन चरित्र का उत्पादन करें, और एक को घटाएं।
$((${#$(readlink -f /etc/fstab; echo .)} - 1))
यदि आप जो चाहते हैं वह कमांड के आउटपुट में पेलोड है, तो आपको यहां दो को घटाना होगा , क्योंकि आउटपुट का readlink -f
विहित पथ प्लस एक नई रेखा है।
$((${#$(readlink -f /etc/fstab; echo .)} - 2))
यह ${#$(readlink -f /etc/fstab)}
दुर्लभ लेकिन संभव मामले से भिन्न होता है जहां विहित पथ स्वयं एक नई रेखा में समाप्त होता है।
इस विशिष्ट उदाहरण के लिए, आपको बाहरी उपयोगिता की आवश्यकता नहीं है, क्योंकि zsh में एक अंतर्निहित निर्माण है जो readlink -f
इतिहास संशोधक के बराबर है A
।
echo /etc/fstab(:A)
लंबाई पाने के लिए, पैरामीटर विस्तार में इतिहास संशोधक का उपयोग करें:
${#${:-/etc/fstab}:A}
यदि आपके पास चर में फ़ाइल का नाम है filename
, तो यह होगा ${#filename:A}
।
बॉर्न / POSIX- शैली के गोले
शुद्ध बोर्न / पोसिक्स गोले (बॉर्न, ऐश, मकश, ksh93, बैश, यश ...) में से कोई भी समान विस्तार नहीं है जो मुझे पता है। यदि आपको कमांड प्रतिस्थापन के आउटपुट या नेस्ट पैरामीटर प्रतिस्थापन के लिए एक पैरामीटर प्रतिस्थापन लागू करने की आवश्यकता है, तो क्रमिक चरणों का उपयोग करें।
यदि आप चाहें तो प्रोसेसिंग को एक फंक्शन में स्टफ कर सकते हैं।
command_output_length_sans_trailing_newlines () {
set -- "$("$@")"
echo "${#1}"
}
या
command_output_length () {
set -- "$("$@"; echo .)"
echo "$((${#1} - 1))"
}
लेकिन आमतौर पर कोई फायदा नहीं होता; ksh93 को छोड़कर, जो फ़ंक्शन के आउटपुट का उपयोग करने में सक्षम होने के लिए एक अतिरिक्त कांटा का कारण बनता है, इसलिए यह आपकी स्क्रिप्ट को धीमा कर देता है, और शायद ही कभी कोई पठनीयता लाभ होता है।
एक बार फिर, का उत्पादन readlink -f
कैनोनिकल पथ और एक नई रेखा है; यदि आप विहित पथ की लंबाई चाहते हैं, तो 1 के बजाय 2 को घटाएं command_output_length
। उपयोग करना command_output_length_sans_trailing_newlines
सही परिणाम देता है जब विहित पथ स्वयं एक नई रेखा में समाप्त नहीं होता है।
बाइट्स बनाम वर्ण
${#…}
वर्णों में लंबाई माना जाता है, बाइट्स में नहीं, जो मल्टीबाइट स्थानों में अंतर करता है। Ksh93, bash और zsh के उचित रूप से अद्यतित संस्करण LC_CTYPE
उस समय के मान के अनुसार वर्णों में लंबाई की गणना करते हैं , जब ${#…}
निर्माण का विस्तार होता है। कई अन्य सामान्य गोले वास्तव में मल्टीबाइट स्थानों का समर्थन नहीं करते हैं: जैसे कि डैश 0.5.7, mksh 46 और पॉश 0.12.3, ${#…}
बाइट्स में लंबाई लौटाता है। यदि आप पात्रों की लंबाई विश्वसनीय तरीके से चाहते हैं, तो wc
उपयोगिता का उपयोग करें :
$(readlink -f /etc/fstab | wc -m)
जब तक $LC_CTYPE
आप एक वैध लोकेल को डिज़ाइन करते हैं, तब तक आप आश्वस्त हो सकते हैं कि यह या तो त्रुटि देगा (एक प्राचीन या प्रतिबंधित प्लेटफ़ॉर्म जो मल्टीबाइट स्थानों का समर्थन नहीं करता है) या वर्णों में सही लंबाई लौटाता है। (यूनिकोड के लिए, "वर्णों में लंबाई" का अर्थ है कोड बिंदुओं की संख्या - ग्लिफ़ की संख्या अभी तक एक और कहानी है, जो कि पात्रों के संयोजन जैसी जटिलताओं के कारण है।)
यदि आप बाइट्स में लंबाई चाहते हैं, तो LC_CTYPE=C
अस्थायी रूप से सेट करें , या wc -c
इसके बजाय का उपयोग करें wc -m
।
बाइट्स या वर्णों की गिनती wc
कमांड के किसी भी अनुगामी newlines में शामिल है। यदि आप बाइट्स में विहित पथ की लंबाई चाहते हैं, तो यह है
$(($(readlink -f /etc/fstab | wc -c) - 1))
वर्णों में प्राप्त करने के लिए, 2 को घटाएं।
readlink -f /etc/fstab
है 11 अक्षर। न्यूलाइन को न भूलें। अन्यथा आप देखेंगे/etc/fstabluser@cern:~$
कि आपने इसे शेल से कब चलाया था।