मैं एक यूनिक्स कमांड का उपयोग करके टेक्स्ट फ़ाइल की प्रत्येक पंक्ति में वर्णों की संख्या प्रिंट करना चाहूंगा। मुझे पता है कि यह पॉवरशेल के साथ सरल है
gc abc.txt | % {$_.length}
लेकिन मुझे यूनिक्स कमांड की जरूरत है।
जवाबों:
आवक का उपयोग करें।
awk '{ print length }' abc.txt
while IFS= read -r line; do echo ${#line}; done < abc.txt
यह POSIX है, इसलिए इसे हर जगह काम करना चाहिए।
संपादित करें: विलियम द्वारा सुझाए गए अनुसार जोड़ा गया।
संपादित करें: यूनिकोड हैंडलिंग से सावधान रहें। बैश और zsh, सही ढंग से सेट लोकेल के साथ, कोडपॉइंट्स की संख्या दिखाएगा, लेकिन डैश बाइट्स दिखाएगा - इसलिए आपको यह जांचना होगा कि आपका शेल क्या करता है। और फिर यूनिकोड में लंबाई की कई अन्य संभावित परिभाषाएं हैं, इसलिए यह इस बात पर निर्भर करता है कि आप वास्तव में क्या चाहते हैं।
संपादित करें: IFS=
अग्रणी और अनुगामी रिक्त स्थान खोने से बचने के लिए उपसर्ग ।
IFS=
पर सेट read
करें। तो IFS= read -r
। शब्द विभाजन करने के लिए read
उपयोग करता है IFS
, और भले ही सभी विभाजित शब्द फिर से एक उपलब्ध चर ( line
) में एक साथ चिपकाए जाते हैं, इस बात की कोई गारंटी नहीं है कि वे सभी मूल विभाजक वर्णों के साथ वापस चिपक जाते हैं जो उनके पास थे या सिर्फ एक संभावित रूप से अलग लोगों को। उदाहरण के लिए, डिफ़ॉल्ट IFS के साथ, लाइन foo bar
बन सकता है foo bar
, 7 रिक्त स्थान खो सकता है । (जैसे कैसे स्टैक ओवरफ्लो ने इस टिप्पणी में उस उदाहरण स्ट्रिंग में आसन्न रिक्त स्थान खो दिया है)।
IFS
सेट होना चाहिए, लेकिन समस्या यह नहीं है जब यह अधिक सूक्ष्म है।
मैंने ऊपर सूचीबद्ध अन्य उत्तरों की कोशिश की है, लेकिन बड़ी फ़ाइलों के साथ काम करते समय वे सभ्य समाधानों से बहुत दूर हैं - विशेष रूप से एक बार एक पंक्ति का आकार उपलब्ध रैम के ~ 1/4 से अधिक हो जाता है।
इस समस्या के लिए भले ही इसकी आवश्यकता न हो, दोनों को पूरी तरह से काट-छाँट करते हैं। यदि आपके पास पर्याप्त मेमोरी है, तो बैश एक लाइन बहुत लंबी होने पर त्रुटि करेगा।
मैंने एक बहुत ही सरल, काफी अडॉप्टेड पाइथन स्क्रिप्ट को लागू किया है, जब बड़ी फ़ाइलों (~ 4 जीबी प्रति पंक्ति) के साथ परीक्षण किया जाता है, तो थप्पड़ नहीं पड़ता है, और अब तक दिए गए से बेहतर समाधान है।
यदि यह उत्पादन के लिए महत्वपूर्ण समय है, तो आप C में विचारों को फिर से लिख सकते हैं या रीड कॉल पर बेहतर अनुकूलन कर सकते हैं (केवल एक बार में एक बाइट पढ़ने के बजाय), परीक्षण के बाद कि यह वास्तव में एक अड़चन है।
कोड मानता है कि न्यूलाइन एक लाइनफीड चरित्र है, जो यूनिक्स के लिए एक अच्छी धारणा है, लेकिन मैक ओएस / विंडोज पर वाईएमएमवी। सुनिश्चित करें कि अंतिम पंक्ति वर्ण गणना को नजरअंदाज नहीं किया गया है यह सुनिश्चित करने के लिए फाइल एक लाइनफीड के साथ समाप्त होती है।
from sys import stdin, exit
counter = 0
while True:
byte = stdin.buffer.read(1)
counter += 1
if not byte:
exit()
if byte == b'\x0a':
print(counter-1)
counter = 0
यहाँ उदाहरण का उपयोग कर रहा है xargs
:
$ xargs -d '\n' -I% sh -c 'echo % | wc -c' < file
इसे इस्तेमाल करे:
while read line
do
echo -e |wc -m
done <abc.txt
echo -e | wc -m
, तुम नहीं थे? यह आदेशों का बेकार उपयोग है; शेल एक चर में वर्णों की गणना कर सकता है। प्लस echo -e
पूरी तरह से असंगत है और आधे भाग में काम करता है जबकि कुछ भागने के क्रम से शुरू होता है और कुछ अन्य में काम करता है।