किसी फ़ाइल की पहली पंक्ति को हटाने के लिए sed
बनाम tail
का प्रदर्शन
टी एल; डॉ
sed
बहुत शक्तिशाली और बहुमुखी है, लेकिन यह वह है जो इसे धीमा करता है, विशेष रूप से कई लाइनों के साथ बड़ी फ़ाइलों के लिए।
tail
सिर्फ एक साधारण बात करता है, लेकिन यह एक अच्छी तरह से और तेजी से करता है, यहां तक कि कई लाइनों के साथ बड़ी फ़ाइलों के लिए भी।
छोटे और मध्यम आकार की फ़ाइलों के लिए, sed
और tail
आपकी उम्मीदों के आधार पर समान तेज़ी से (या धीमी गति से) प्रदर्शन कर रहे हैं। हालांकि, बड़ी इनपुट फ़ाइलों (कई एमबी) के लिए, tail
स्पष्ट रूप से बेहतर प्रदर्शन के साथ, प्रदर्शन अंतर काफी बढ़ जाता है (सैकड़ों एमबी की सीमा में फाइलों के लिए परिमाण का एक क्रम) sed
।
प्रयोग
सामान्य तैयारी:
विश्लेषण करने के लिए हमारे आदेश हैं:
sed '1d' testfile > /dev/null
tail -n +2 testfile > /dev/null
ध्यान दें कि मैं /dev/null
टर्मिनल आउटपुट को खत्म करने के लिए हर बार आउटपुट को पाइप कर रहा हूं या प्रदर्शन अड़चन के रूप में फाइल लिखता हूं ।
आइए डिस्क I / O को संभावित अड़चन के रूप में समाप्त करने के लिए एक रैम डिस्क सेट करें। मेरे पास व्यक्तिगत रूप से एक tmpfs
घुड़सवार है /tmp
इसलिए मैंने बस testfile
इस प्रयोग के लिए वहां रखा ।
फिर मैं एक बार एक यादृच्छिक परीक्षण फ़ाइल बना रहा हूं जिसमें इस $numoflines
लाइन का उपयोग करके यादृच्छिक लाइन की लंबाई और यादृच्छिक डेटा के साथ निर्दिष्ट मात्रा है (ध्यान दें कि यह निश्चित रूप से इष्टतम नहीं है, यह लगभग> 2M लाइनों के लिए धीमा हो जाता है, लेकिन कौन परवाह करता है, यह नहीं है बात हम विश्लेषण कर रहे हैं):
cat /dev/urandom | base64 -w0 | tr 'n' '\n'| head -n "$numoflines" > testfile
ओह, btw। मेरा टेस्ट लैपटॉप उबंटू 16.04, 64 बिट इंटेल आई 5-6200 यू सीपीयू पर चल रहा है। सिर्फ तुलना के लिए।
बड़ी फ़ाइलें समय:
एक विशाल की स्थापना testfile
:
numoflines=10000000
एक यादृच्छिक फ़ाइल का उत्पादन 10M लाइनों के साथ ऊपर से चल रहा है , 600 एमबी से अधिक पर कब्जा कर रहा है - यह काफी बड़ा है, लेकिन हम इसके साथ शुरू करते हैं, क्योंकि हम कर सकते हैं:
$ wc -l testfile
10000000 testfile
$ du -h testfile
611M testfile
$ head -n 3 testfile
qOWrzWppWJxx0e59o2uuvkrfjQbzos8Z0RWcCQPMGFPueRKqoy1mpgjHcSgtsRXLrZ8S4CU8w6O6pxkKa3JbJD7QNyiHb4o95TSKkdTBYs8uUOCRKPu6BbvG
NklpTCRzUgZK
O/lcQwmJXl1CGr5vQAbpM7TRNkx6XusYrO
हमारे विशाल के साथ समयबद्ध प्रदर्शन करें testfile
:
अब हम दोनों आदेशों के साथ केवल एक समयबद्ध रन बनाते हैं, यह अनुमान लगाने के लिए कि हम किस परिमाण के साथ काम कर रहे हैं।
$ time sed '1d' testfile > /dev/null
real 0m2.104s
user 0m1.944s
sys 0m0.156s
$ time tail -n +2 testfile > /dev/null
real 0m0.181s
user 0m0.044s
sys 0m0.132s
हम पहले से ही बड़ी फ़ाइलों के लिए वास्तव में स्पष्ट परिणाम देखते हैं, tail
की तुलना में तेजी से एक परिमाण है sed
। लेकिन सिर्फ मज़े के लिए और यह सुनिश्चित करने के लिए कि कोई बड़ा साइड इफ़ेक्ट नहीं है, कोई फर्क नहीं पड़ता, चलो इसे 100 बार करें:
$ time for i in {1..100}; do sed '1d' testfile > /dev/null; done
real 3m36.756s
user 3m19.756s
sys 0m15.792s
$ time for i in {1..100}; do tail -n +2 testfile > /dev/null; done
real 0m14.573s
user 0m1.876s
sys 0m12.420s
निष्कर्ष एक ही रहता है, sed
एक बड़ी फ़ाइल की पहली पंक्ति को हटाने के लिए अक्षम है, tail
वहां उपयोग किया जाना चाहिए।
और हाँ, मुझे पता है कि बैश के लूप निर्माण धीमी गति से होते हैं, लेकिन हम यहां केवल कुछ पुनरावृत्तियों कर रहे हैं और एक सादा लूप लेने में वैसे भी sed
/ tail
runtimes की तुलना में महत्वपूर्ण नहीं है।
छोटी फ़ाइलें समय:
एक छोटी सी स्थापना testfile
:
अब पूर्णता के लिए, आइए अधिक सामान्य मामले को देखें कि आपके पास kB रेंज में एक छोटी इनपुट फ़ाइल है। आइए numoflines=100
इस तरह की खोज के साथ एक यादृच्छिक इनपुट फ़ाइल बनाएँ :
$ wc -l testfile
100 testfile
$ du -h testfile
8,0K testfile
$ head -n 3 testfile
tYMWxhi7GqV0DjWd
pemd0y3NgfBK4G4ho/
aItY/8crld2tZvsU5ly
हमारे छोटे से समयबद्ध रन का प्रदर्शन करें testfile
:
जैसा कि हम अनुभव से कुछ मिलीसेकंड की सीमा में ऐसी छोटी फ़ाइलों के लिए समय की उम्मीद कर सकते हैं, चलो अभी 1000 पुनरावृत्तियों करते हैं:
$ time for i in {1..1000}; do sed '1d' testfile > /dev/null; done
real 0m7.811s
user 0m0.412s
sys 0m7.020s
$ time for i in {1..1000}; do tail -n +2 testfile > /dev/null; done
real 0m7.485s
user 0m0.292s
sys 0m6.020s
जैसा कि आप देख सकते हैं, समय काफी समान हैं, के बारे में व्याख्या या आश्चर्य करने के लिए बहुत कुछ नहीं है। छोटी फ़ाइलों के लिए, दोनों उपकरण समान रूप से अच्छी तरह से अनुकूल हैं।
sed
लिए अधिक पोर्टेबल: "+2" हैtail
, जो GNU का उपयोग करता हैtail
, लेकिन BSD पर काम नहीं करेगाtail
।