एक निश्चित लंबाई से अधिक की कोई भी रेखा खोजें


52

क्या किसी फ़ाइल में 79 वर्णों से अधिक की लाइनें ढूंढना संभव है?

जवाबों:


89

मेरे परीक्षणों के अनुसार गति में कमी (UTF-8 लोकेल और ASCII इनपुट में GNU सिस्टम पर):

grep '.\{80\}' file

perl -nle 'print if length$_>79' file

awk 'length>79' file

sed -n '/.\{80\}/p' file

सिवाय for perlएक (या awk/ grep/ sedकार्यान्वयन (जैसे mawkया बिजीबॉक्स) के लिए जो मल्टी-बाइट वर्णों का समर्थन नहीं करते हैं) को छोड़कर , जो कि बाइट्स के बजाय वर्णों की संख्या ( LC_CTYPEस्थानीय की सेटिंग के अनुसार ) के संदर्भ में लंबाई की गणना करता है ।

यदि इनपुट में बाइट्स हैं जो वैध वर्णों का हिस्सा नहीं बनते हैं (जो कि कभी-कभी तब होता है जब लोकेल का वर्ण सेट UTF-8 और इनपुट एक अलग एन्कोडिंग में होता है), तो समाधान और उपकरण कार्यान्वयन के आधार पर, उन बाइट्स या तो 1 वर्ण के रूप में गिना जाएगा, या 0 या मेल नहीं खाएगा .

उदाहरण के लिए, एक लाइन जिसमें 30 asa 0x80 बाइट, 30 bs, एक 0x81 बाइट और 30 UTF-8 és (0xc3 0xa9 के रूप में इनकोडिंग) होती है, UTF-8 लोकेल में .\{80\}GNU grep/ sed(उस स्टैंडअलोन 0x80 बाइट से मेल नहीं खाती है) मेल नहीं खाता .), की लंबाई 30 + 1 + 30 + 1 + 2 * 30 = 122 के साथ perlया mawk, 3 * 30 = 90 के साथ होगी gawk

आप बाइट्स के मामले में गिनती करने के लिए चाहते हैं, करने के लिए स्थान तय Cसाथ LC_ALL=C grep/awk/sed...

सभी 4 समाधानों पर विचार करना होगा कि ऊपर की पंक्ति में 122 वर्ण हैं। ( perlGNU टूल) को छोड़कर , आपके पास अभी भी NUL अक्षर (0x0 बाइट) वाली लाइनों के लिए संभावित समस्याएँ होंगी।


¹ perlव्यवहार PERL_UNICODEहालांकि पर्यावरण चर से प्रभावित हो सकता है


"कुशल" से आपका क्या अभिप्राय है?
रैलेंट्रान

मुझे लगता है कि मैनटवर्क का मतलब टाइपिंग दक्षता है। awkयदि आप ड्रॉप करते हैं ($0), तो यह करीब आ सकता है , जो वैसे भी निहित है;)।
थोर

9
BTW, यदि आप लाइन की शुरुआत में regexp को एंकर करते हैं, तो ^यह थोड़ा तेज है: उदा grep '^.\{80\}' file
कैस

4
पर्ल समाधान अन्य सभी समाधानों के विपरीत, यूटीएफ -8 जैसे चर आकार के एन्कोडिंग के लिए जिम्मेदार नहीं है।
बैचैक्स

6
N के पर्याप्त बड़े मूल्य grep के साथ विफल होते हैं लेकिन awk के साथ सफल होते हैं। (उदाहरण के लिए grep '^.\{1000\}' fileरिटर्न grep: invalid repetition count(s), जबकि awk 'length>1000' fileसफल होता है।)
mdahlman

1

शेल दृष्टिकोण:

while IFS= read -r line || [ -n "$line" ];
do 
    [ "${#line}" -gt 79 ] && printf "%s\n" "$line"
done < input.txt

अजगर दृष्टिकोण:

python -c 'import sys;f=open(sys.argv[1]);print "\n".join([ l.strip() for l in f if len(l) >79 ]);f.close()' input.txt

या पठनीयता के लिए एक छोटी स्क्रिप्ट के रूप में:

#!/usr/bin/env python
import sys

with open(sys.argv[1]) as f:
    for line in f:
        if len(line) > 79:
            print line.strip()

अगर हम न्यू लाइन चरित्र को बाहर करना चाहता था \nगणनाओं से, हम कर सकते हैं if len(line) > 79हो सकता हैif len(line.strip()) > 79

साइड नोट: यह पायथन 2.7 सिंटैक्स है। print()पायथन 3 के लिए उपयोग करें

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.