`Wc -l` कैसे काम करता है?


11

मुझे एक बड़ी फ़ाइल पढ़नी है और इससे पहले कि मैं इसे पढ़ना शुरू करूँ, मुझे फ़ाइल में कुल पंक्तियों (जो लाखों में हैं) को जानना होगा।

मैंने बहुत सारे समाधान लागू किए हैं और एक पाया है। लेकिन अपनी खोज के दौरान मैं यह देखने के लिए सोच रहा था कि कैसे wc -lकाम करता है। मुझे Google पर कुछ भी नहीं मिला।

हालाँकि मुझे अपनी समस्या का हल मिल गया है, फिर भी मैं यह जानना चाहूंगा कि यह कैसे wc -lकाम करता है क्योंकि यह कुछ सेकंड में 92 मिलियन लाइनों वाली फाइल की लाइनों की गणना कर सकता है!

कैसे?


जवाबों:


20

यह पूरी फाइल को पढ़ता है और लाइन-एंडिंग की संख्या को गिनता है। लाइन अंत की गिनती वास्तव में सस्ती है; बिताया गया अधिकांश समय फ़ाइल को पढ़ रहा है। यदि फ़ाइल बफर कैश में (ज्यादातर) होती है, तो वह भी सस्ती होगी। अन्यथा, यह आपकी फ़ाइल संग्रहण की गति पर निर्भर करेगा।

दूसरे शब्दों में, कोई जादू नहीं है।


यह संपूर्ण फ़ाइल पढ़ता है और पंक्ति समाप्ति की संख्या को गिनता है? लाइन समाप्त होने के लिए, क्या यह मूल रूप से पूरी लाइन को तब तक नहीं पढ़ता है जब तक यह अंत तक नहीं पहुंचता है? और इसका मतलब यह होगा कि यह पूरी फ़ाइल को पढ़ा, है ना?
डेट्रायलर

@detraveller: हाँ, यह पूरी फाइल को पढ़ता है, जैसे मैंने कहा। यह लाइन से लाइन या सभी को एक साथ नहीं पढ़ता है, लेकिन यह हर वर्ण को पढ़ता है और गिनता है कि उन वर्णों में से कितने पंक्ति-अंत वर्ण हैं।
रिसी

7

WC केवल कच्चे बाइट्स के ब्लॉक में फाइल पढ़ता है (अंतर्निहित फाइल सिस्टम के प्राकृतिक ब्लॉक-आकार के गुणकों में बेहतर है, जिस पर फ़ाइल स्थित है)।
फिर यह केवल अंत वर्णों की गिनती करने वाले बफर के माध्यम से स्कैन करता है। (यह भी रिक्त स्थान, टैब, फॉर्म-फीड और अन्य विशेष वर्णों को गिनता है, बस मामले में आप -l आउटपुट से अन्य जानकारी चाहते थे।)

डिस्क से पढ़ना गति के मामले में महंगा हिस्सा है। बफर की स्कैनिंग की तुलना में उपेक्षा-सक्षम समय लगता है।

मान लें कि आपको प्रति पंक्ति औसतन 100 वर्णों के साथ 90 मिलियन लाइनें मिली हैं।
यह लगभग 9.000.000.000 अक्षर या लगभग 860 MB है।
SATA-3Gb / s ड्राइव के साथ एक सभ्य पीसी 10 सेकंड के भीतर ऐसा करेगा। यहां तक ​​कि अपेक्षाकृत धीमी गति से फाइल सिस्टम पर कुछ अन्य गतिविधि एक ही समय में चल रही है।
SATA-6G और एक SSD ड्राइव का सहारा लिए बिना, कुछ प्रदर्शन ट्यूनिंग और एक अनुकूलित फाइल सिस्टम के साथ एक तेज़ मशीन इसे 5 सेकंड में कर सकती है।


यह सिर्फ बफर के माध्यम से स्कैन करता है जो अंत-पंक्ति ( \n) वर्णों की गिनती करता है - "-l, --lines नईलाइन की संख्या प्रिंट करता है \ n \" - से निकाला गयाwc.c
राहुल पाटिल

@RahulPatil अधिकांश कार्यान्वयन केवल नई गणना की तुलना में बहुत अधिक करते हैं। ऊपर दिए गए शीर्ष टिप्पणी में उल्लिखित उदाहरण देखें। यह Linux कोर उपयोगिताओं में wc का स्रोत है।
टॉनी

हाँ .. मैंने देखा है कि .. सिर्फ इसलिए कि मैं उल्लेख करता हूँ, के बारे में सवाल wc -l.. क्षमा करें ...
राहुल पाटिल

3

मुफ्त सॉफ्टवेयर की दुनिया में आपका स्वागत है। आप हमेशा स्रोत कोड देख सकते हैं

हालांकि मुझे यह स्वीकार करना चाहिए कि मैं एक सी प्रोग्रामर नहीं हूं, इसलिए मैं ऐसा नहीं हूं जो वास्तव में आपके लिए कोड की व्याख्या कर सके (और मुझे खुद को समझा जाएगा)।

मुझे पता है कि चूंकि wc फ़ाइल को स्वयं नहीं खोलता है, लेकिन OS को ऐसा करने के लिए कहता है, यह काफी हद तक OS पर निर्भर करता है, और निश्चित रूप से, फ़ाइल कैसे संग्रहीत है। इसके अलावा, मैं उम्मीद करूंगा कि सही प्रोग्रामिंग प्रथाएं लागू होनी चाहिए, उदाहरण के लिए फ़ाइल को एक बार में पढ़ने की कोशिश नहीं करना, आदि।


'एक बार में पूरी फ़ाइल पढ़ने की कोशिश नहीं करने' का क्या मतलब है?
डेट्रेलर

मेरा मतलब है कि फ़ाइल को मेमोरी में लोड करना, एक स्ट्रिंग / सरणी के लिए कहना। पर्ल समुदाय में इसे स्लुरपिंग कहा जाता है, और यह एक त्वरित और गंदा समाधान है जो ठीक है जब आप जानते हैं कि आप कुछ पंक्तियां पढ़ रहे होंगे, लेकिन एक बार में स्मृति में वास्तव में बहुत बड़ी फ़ाइल को खिलाना एक अच्छा विचार है।
एलोइस महदाल

1
दूसरी ओर, आप 64 KiB को पढ़ सकते हैं, कह सकते हैं कि नई संख्याओं को गिनें और इसे दूर फेंक दें, दोहराएं ... इस तरह से आप 64 KiB पर कुछ खाएंगे, चाहे वह कितनी भी बड़ी फ़ाइल क्यों न हो। (यह कम आसान है जब आपको पता चलता है कि न्यूलाइन में 2 बाइट्स हो सकते हैं और इस तरह 2 विखंडू के बीच विभाजित हो सकते हैं; अब यह वह जगह है जहाँ से शुरू होता है)
Alois Mahdal

बहुत महत्वपूर्ण नहीं है, लेकिन: "चूंकि wc फ़ाइल को स्वयं नहीं खोलता है, लेकिन OS को ऐसा करने के लिए कहता है" - सुनिश्चित नहीं है कि आपका क्या मतलब है, लेकिन मुझे संदेह है कि यह सही है। यह निश्चित रूप से सभी पात्रों को स्वयं पढ़ रहा है।
अर्जन

2
@ अर्जन हालांकि, वास्तव में सही होने के लिए: एम्बेडेड सिस्टम को छोड़कर, प्रोग्राम शायद ही वास्तव में खुद को पढ़ते हैं, कर्नेल और ओएस का पूरा बिंदु यह है कि यह उनके लिए काम करता है। वास्तव में, ओपन (), क्लोज (), रीड () (यह लिनक्स, विंडोज, सॉकेट या फ़ाइल हो) सभी सिस्टम कॉल हैं जो वास्तविक कार्यक्रमों में आंतरिक कामकाज का कोई विचार नहीं है।
एलोइस महदाल
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.