पहली सबसे लंबी लाइन ग्रीप
grep -Em1 "^.{$(wc -L <file.txt)}\$" file.txt
यह अभ्यास के बिना पढ़ने के लिए कमांड असामान्य रूप से कठिन है क्योंकि यह शेल- और रेक्सएक्सपी सिंटैक्स को मिलाता है।
स्पष्टीकरण के लिए, मैं पहले सरलीकृत स्यूडोकोड का उपयोग करूंगा। से शुरू होने वाली रेखाएं ##
शेल में नहीं चलती हैं।
यह सरलीकृत कोड फ़ाइल नाम F का उपयोग करता है, और पठनीयता के लिए उद्धरण और regexps के कुछ हिस्सों को छोड़ देता है।
यह काम किस प्रकार करता है
कमांड के दो भाग हैं, एक grep
- और एक wc
मंगलाचरण:
## grep "^.{$( wc -L F )}$" F
wc
एक प्रक्रिया विस्तार में प्रयोग किया जाता है, $( ... )
, तो यह पहले से चलाया जाता है grep
। यह सबसे लंबी रेखा की लंबाई की गणना करता है। शेल एक्सपोज़र सिंटैक्स को एक अभिव्यक्ति तरीके से नियमित अभिव्यक्ति पैटर्न सिंटैक्स के साथ मिलाया जाता है, इसलिए मैं प्रक्रिया विस्तार को विघटित करूंगा:
## wc -L F
42
## grep "^.{42}$" F
यहां, प्रक्रिया विस्तार को उस मान के साथ बदल दिया गया था, grep
जिसका उपयोग कमांडलाइन बनाते हुए किया जाएगा। अब हम नियमित अभिव्यक्ति को अधिक आसानी से पढ़ सकते हैं: यह लाइन के प्रारंभ ( ^
) से अंत ( $
) तक बिल्कुल मेल खाता है । उनके बीच की अभिव्यक्ति न्यूलाइन को छोड़कर किसी भी चरित्र से मेल खाती है, जिसे 42 बार दोहराया गया। संयुक्त, वह रेखाएँ जिनमें 42 अक्षर होते हैं।
अब, वास्तविक शेल कमांड पर वापस: grep
विकल्प -E
( --extended-regexp
) {}
पठनीयता के लिए बचने की अनुमति नहीं देता है। पहली पंक्ति मिलने के बाद विकल्प -m 1
( --max-count=1
) इसे बंद कर देता है। <
में wc
आदेश को रोकने के लिए अपने stdin के लिए फ़ाइल लिखता है, wc
लंबाई के साथ एक साथ फ़ाइल नाम मुद्रण से।
कौन सी सबसे लंबी रेखाएं?
दो बार होने वाले फ़ाइलनाम के साथ उदाहरणों को अधिक पठनीय बनाने के लिए, मैं f
फ़ाइल नाम के लिए एक चर का उपयोग करूंगा ; $f
उदाहरण में प्रत्येक को फ़ाइल नाम से बदला जा सकता है।
f="file.txt"
पहली लंबी लाइन दिखाएं - पहली लाइन जो सबसे लंबी लाइन जितनी लंबी हो:
grep -E -m1 "^.{$(wc -L <"$f")}\$" "$f"
सभी लंबी लाइनों को दिखाएं - सभी लाइनें जो सबसे लंबी लाइन के रूप में लंबी हैं:
grep -E "^.{$(wc -L <"$f")}\$" "$f"
अंतिम लंबी लाइन दिखाएं - आखिरी लाइन जो सबसे लंबी लाइन है:
tac "$f" | grep -E -m1 "^.{$(wc -L <"$f")}\$"
एकल लंबी लाइन दिखाएँ - अन्य सभी लाइनों की तुलना में सबसे लंबी लाइन, या विफल:
[ $(grep -E "^.{$(wc -L <"$f")}\$" "$f" | wc -l) = 1 ] && grep -E "^.{$(wc -L <"$f")}\$" "$f"
(अंतिम कमांड अन्य की तुलना में अधिक अक्षम है, क्योंकि यह पूरी grep कमांड को दोहराता है। इसे स्पष्ट रूप से विघटित किया जाना चाहिए ताकि इसके wc
द्वारा लिखी गई लाइनों और आउटपुट grep
को वेरिएबल्स में बचाया जा सके।
ध्यान दें कि सभी लंबी लाइनें वास्तव में सभी लाइनें हो सकती हैं। एक चर में बचत के लिए, केवल पहली दो पंक्तियों को रखने की आवश्यकता है।)