Grep उर्फ ​​- लाइन नंबर जब तक यह एक पाइपलाइन में नहीं है


25

मैं grep के लिए एक bash उपनाम बनाना चाहता हूं जो लाइन नंबर जोड़ता है:

alias grep='grep -n'

लेकिन, निश्चित रूप से, पाइपलाइनों के लिए लाइन नंबर भी जोड़ता है। ज्यादातर समय (और कोई अपवाद नहीं आता है) मुझे पाइपलाइन के भीतर लाइन नंबर नहीं चाहिए (कम से कम आंतरिक रूप से, शायद ठीक है अगर यह आखिरी है), और मैं वास्तव में एक sed / awk / cut नहीं जोड़ना चाहता / चाहती हूं बस उन्हें बाहर निकालने के लिए पाइपलाइन।

शायद मेरी आवश्यकताओं को सरल बनाया जा सकता है "केवल लाइन संख्याओं को जोड़ने के लिए अगर grep लाइन पर एकमात्र कमांड है।" वहाँ एक विशेष रूप से बदसूरत उपनाम के बिना यह करने के लिए कोई रास्ता नहीं है?

जवाबों:


27

आप इस तरह से bash (या किसी भी POSIX शेल) में एक फंक्शन का उपयोग कर सकते हैं:

grep() { 
    if [ -t 1 ] && [ -t 0 ]; then 
        command grep -n "$@"
    else 
        command grep "$@"
    fi
}

यह जाँच करने के लिए कि क्या स्टडीआउट एक छोटे से जुड़ा हुआ है, यह [ -t 1 ]हिस्सा [कमांड (जिसे भी जाना जाता है test) का उपयोग करता है ।

[ -t 0 ]चेकों मानक इनपुट, साथ ही, जब से तुम केवल लाइन नंबर जोड़ने के लिए निर्दिष्ट करता है, तो grepहै ही पाइप लाइन में आदेश।


5
और परीक्षण करें [[ -t 0 && -t 1 ]]यदि आप केवल लाइन नंबर चाहते हैं यदि मानक इनपुट और मानक आउटपुट दोनों एक टर्मिनल से जुड़े हैं।
गिल्स एसओ- बुराई को रोकना '

3

(संपूर्णता के लिए)

जबकि @ enzotib का जवाब शायद सबसे ज्यादा वही है जो आप चाहते हैं, यह वह नहीं है जो आपने मांगा था। [ -t 1 ]जाँचता है कि फ़ाइल डिस्क्रिप्टर एक टर्मिनल डिवाइस है, न कि यह पाइप के अलावा और कुछ भी नहीं है (जैसे एक नियमित फ़ाइल, सॉकेट, डिवाइस का एक अन्य प्रकार /dev/null...)

[आदेश का कोई बराबर है -tलेकिन पाइप के लिए। फाइल डिस्क्रिप्टर से जुड़ी फाइल का प्रकार प्राप्त करने के लिए, आपको उस पर fstat()सिस्टम कॉल करने की आवश्यकता है। ऐसा करने के लिए कोई मानक कमांड नहीं है, लेकिन कुछ सिस्टम या शेल में कुछ हैं।

GNU के साथ stat:

grep() {
  if { [ "$(LC_ALL=C stat -c %F - <&3)" = fifo ]; } 3>&1 ||
     [ "$(LC_ALL=C stat -c %F -)" = fifo ]; then
    command grep "$@"
  else
    command grep -n "$@"
  fi
}

या zshअपने स्वयं के statबिलिन के साथ (जो कुछ वर्षों में जीएनयू की एक भविष्यवाणी करता है), यहां zstatकेवल लोड किया गया है :

grep() {
  zmodload -F zsh/stat b:zstat
  local stdin_type stdout_type
  if zstat -A stdin_type -s -f 0 +mode &&
     zstat -A stdout_type -s -f 1 +mode &&
     [[ $stdin_type = p* || $stdout_type = p* ]]
  then
     command grep "$@"
  else
     command grep -n "$@"
  fi
}

अब कुछ नोट:

यह न केवल शेल पाइपलाइन हैं जो पाइप का उपयोग करते हैं।

var=$(grep foo bar)

या:

cmd <(grep foo bar)

या:

coproc grep foo bar

भी चलाने के grepअपने stdout एक पाइप को मिल गया।

यदि आपका शेल है ksh93, तो ध्यान दें कि कुछ सिस्टम पर, यह अपनी पाइपलाइनों में पाइप के बजाय सॉकेटपेयर का उपयोग करता है।

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