सभी लाइनों का उत्पादन करने के लिए grep को मनाएं, न कि केवल मिलान वाले


121

कहो कि मेरे पास निम्न फ़ाइल है:

$ cat test

test line 1
test line 2
line without the search word
another line without it
test line 3 with two test words
test line 4

डिफ़ॉल्ट रूप से, grepखोज शब्द में प्रत्येक पंक्ति देता है:

$ grep test test

test line 1
test line 2
test line 3 with two test words
test line 4

--colorपैरामीटर को पास करने के grepलिए यह खोज अभिव्यक्ति से मेल खाने वाली रेखा के हिस्से को उजागर करेगा, लेकिन यह अभी भी केवल उन पंक्तियों को वापस करता है जिनमें अभिव्यक्ति होती है। क्या grepस्रोत फ़ाइल में प्रत्येक पंक्ति को आउटपुट करने का एक तरीका है , लेकिन मैचों को हाइलाइट करें?

इसे पूरा करने के लिए मेरी वर्तमान भयानक हैक (कम से कम उन फ़ाइलों पर जिनके पास बिना मिलान के 10000+ लगातार लाइनें हैं):

$ grep -B 9999 -A 9999 test test

दो आज्ञाओं का स्क्रीनशॉट

यदि grepइसे पूरा नहीं किया जा सकता है, तो क्या कोई अन्य कमांड लाइन टूल है जो समान कार्यक्षमता प्रदान करता है? मैंने इसके साथ काम किया है ack, लेकिन इसके लिए कोई विकल्प नहीं है।


1
की संभावित क्रॉस साइट डुप्लिकेट: stackoverflow.com/questions/981601/… शीर्ष उत्तर दोनों पर समान है।
सिरो सेंटिल्ली 新疆 改造 iro 六四 事件 '

1
आप उपयोग कर सकते हैं -C 9999के स्थान पर -A 9999 -B 9999मैं हमेशा कार्य करें:grep -C 9999 pattern file
नव

जवाबों:


181
grep --color -E "test|$" yourfile

हम यहां जो कर रहे हैं वह $पैटर्न और टेस्ट पैटर्न के खिलाफ मेल $खा रहा है , जाहिर है कोलॉज़ के लिए कुछ भी नहीं है इसलिए केवल टेस्ट पैटर्न को रंग मिलता है। -Eबस विस्तारित रेगुलर एक्सप्रेशन मिलान का चालू करता है।

आप इसमें से एक फंक्शन आसानी से बना सकते हैं:

highlight () { grep --color -E "$1|$" "${@:1}" ; }

14
यह बहुत बढ़िया है!
gvkv

3
और एक समारोह के रूप में highlight () { grep --color -E "$1|$" $2 ; }:। उपयोग:highlight test yourfile
स्टीफन लासिवस्की

2
@StefanLasiewski: "$2"भी उद्धृत किया जाना चाहिए।
डेनिस विलियमसन

6
बेहतर हो सकता है: highlight () { grep --color -E "$1|$" "$@" }जो अपने नाम और कई फाइलों में व्हॉट्सएप के साथ फाइल की अनुमति देता है ।
माइक डिसमोन

15
@MikeDeSimone - लेकिन वह भी "$1"फाइलों में होगा। उपयोगhighlight () { grep --color -E "$1|$" "${@:1}" }
क्रिस डाउन

39
ack --passthru --color string file

उबंटू और डेबियन के लिए, ऐक के बजाय एक-जीआरईपी का उपयोग करें

ack-grep --passthru --color string file

1
ओह, यह काफी स्पष्ट रूप से मैन पेज में है; मैं अंधा हूँ। धन्यवाद
माइकल Mrozek

अंगूर के लिए पैटर्न के साथ स्पष्ट रूप से निर्दिष्ट किया जा सकता है --regexp string; ack / ack-grep समतुल्य है--match string
Rhubbarb

ack --passthruपर्ल के साथ अनुकरण करने के लिए :grep_passthrough () { ! perl -ne "print; \$e ||= /$@/; END{{exit \$e}}"; }
लुकास साइमन

ack --passthruधाराओं पर भी काम करता है! उदाहरण के लिए,ifconfig | ack --passthru inet
honkaboy

12

एक अन्य तरीका यह करने के लिए ठीक से और portably साथ grep(स्वीकार किए जाते हैं जवाब में के रूप में प्रत्यावर्तन के साथ दो regexes का उपयोग कर के अलावा) अशक्त पैटर्न (और क्रमशः अशक्त स्ट्रिंग) के माध्यम से है।
यह मानक के अनुसार , दोनों -Eऔर -Fस्विच के साथ समान रूप से अच्छी तरह से काम करना चाहिए :

-E
    Match using extended regular expressions. 
    [...] A null ERE shall match every line.

तथा

-F
    Match using fixed strings.
    [...] A null string shall match every line.

तो यह बस चलने की बात है

grep -E -e '' -e 'pattern' infile

और क्रमशः

grep -F -e '' -e 'string' infile

1
या बस grep -F -e '' -e 'string'
स्टीफन चेज़लस

यह मेरे लिए जीएनयू जीआरईपी २.२५, बिजीबॉक्स ग्रीप और हिरलूम टूलचस्ट के साथ काम करता है।
स्टीफन चेज़लस

ठीक है, मेरा बुरा, seq 3 | grep -F -e '' -e 2२.२ my (और २.२६, लेकिन २.२५ में नहीं, और जीआईटी हेड में नहीं) में केवल २ उत्पादन करता है। केवल -F(बिना या बिना ई के साथ)। IOW, केवल 2.26 और 2.27 में बग और केवल -F के साथ लगता है।
स्टीफन चेज़लस

ध्यान दें कि seq 3 | grep -F -e '' -e '' -e 2 2.27 के साथ के रूप में अच्छी तरह से काम करने के लिए प्रतीत होता है
स्टीफन Chazelas

1
इस उत्तर में दी गई विधि सरल, सही और काफी तेज हैजैसा कि आप कहते हैं , यह स्वचालित रूप से काम करता है -F, इस बात की चिंता करने की आवश्यकता है कि इसमें कौन से पात्र दिखाई देते हैं string। आप उल्लेख करना चाह सकते हैं --color; जैसा कि यह उत्तर पृष्ठ पर तैरता है (जब वोटों से देखा जाता है), अधिक लोग अन्य उत्तरों से पहले इसे पढ़ सकते हैं।
एलियाह कगन

11

मेरे पास निम्नलिखित कार्य हैं जो मैं ऐसी चीजों के लिए उपयोग करता हूं:

highlight () {
    perl -pe "s/$1/\e[1;31;43m$&\e[0m/g"
}

आंतरिक रूप से यह एक तरह का बदसूरत लगता है, यह उपयोग करने के लिए अच्छा और आसान है:

cat some_file.txt | highlight some_word

या, थोड़ी और वास्तविक दुनिया के उदाहरण के लिए:

tail -f console.log | highlight ERROR

बदलकर - तुम कुछ भी करने के लिए रंग आप की तरह (I 'm नहीं यकीन है कि ग्रेप साथ कठिन हो सकता है हो सकता है) को बदल सकते हैं 1और 31और 43(के बाद \e[) विभिन्न मूल्यों के लिए। कोड उपयोग कर रहे हैं सब से अधिक जगह है, लेकिन यहाँ एक त्वरित परिचय है: 1 bolds पाठ, 31यह लाल बनाता है, और 43एक पीले रंग की पृष्ठभूमि देता है। 32या 33अलग अलग रंग होगा, और 44या 45अलग पृष्ठभूमि होगा: आप अंदाजा हो। 5यदि आप बहुत इच्छुक हैं तो आप इसे पलक झपकते भी (क ) के साथ कर सकते हैं।

यह किसी विशेष पर्ल मॉड्यूल का उपयोग नहीं करता है, और पर्ल लगभग सर्वव्यापी है, इसलिए मुझे उम्मीद है कि यह कहीं भी काम करेगा। Grep समाधान बहुत चालाक है, लेकिन grep पर --color स्विच हर जगह उपलब्ध नहीं है। उदाहरण के लिए, मैंने बस सोलारिस बॉक्स पर चलने वाले बैश, और एक और चलने वाली ksh और मेरे स्थानीय मैक OS X मशीन को चलाने के लिए इस समाधान की कोशिश की। सब ठीक काम किया। सोलारिस ने grep --colorहालांकि घोल को ठंडा किया ।

इसके अलावा, ऐक भयानक है, और मैं इसे किसी को भी सुझाता हूं जिसने अभी तक इसकी खोज नहीं की है, लेकिन मेरे पास कुछ ऐसे सर्वर हैं जिन्हें मैं काम करता हूं। (मैं भूल जाता हूँ क्यों: मुझे लगता है कि पर्ल से संबंधित यह आवश्यक है।)

चूंकि मुझे नहीं लगता कि मैंने कभी एक यूनिक्स बॉक्स पर काम किया है, जिसमें पर्ल स्थापित नहीं है (एम्बेडेड-टाइप सिस्टम के अपवाद के साथ, लिंक्स राउटर, और ऐसे) मैं कहूंगा कि यह एक सार्वभौमिक रूप से उपयोग करने योग्य समाधान है। ।


3

Grep का उपयोग करने के बजाय, आप कम का उपयोग कर सकते हैं:

less file

इस तरह खोजें: /pattern Enter

यह करेगा:

  1. पहली मिलान रेखा तक स्क्रॉल करें
  2. वहां से शुरू होने वाली हर लाइन का आउटपुट
  3. सभी मैचों को हाइलाइट करें

अगली मिलान रेखा तक स्क्रॉल करने के लिए: n

पिछली मिलान लाइन पर स्क्रॉल करने के लिए: N

हाइलाइटिंग टॉगल करने के लिए: Esc u

यदि आप चाहें तो हाइलाइटिंग रंग भी बदल सकते हैं ।


2

तुम कोशिश कर सकते हो:

perl -MTERM::ANSIColor -nle '/pattern/ ? print colored($_, 'color') : print' test

हालांकि बहुत पोर्टेबल नहीं है, और यहां तक ​​कि अगर पर्ल स्थापित है, तो आपको एक और मॉड्यूल डाउनलोड करने की आवश्यकता हो सकती है। इसके अलावा यह पूरी लाइन को रंग देगा, न कि केवल खोज शब्द।


2

ripgrep

ripgrepइसके --passthruपैरामीटर के साथ उपयोग करें :

rg --passthru pattern file.txt

यह सबसे तेज़ ग्रेपिंग टूल में से एक है , क्योंकि यह रस्ट के रेगेक्स इंजन के शीर्ष पर बनाया गया है , जो बहुत तेजी से खोज करने के लिए परिमित ऑटोमेटा, SIMD और आक्रामक शाब्दिक अनुकूलन का उपयोग करता है।

--passthru - मैचिंग और नॉन-मैचिंग दोनों लाइनों को प्रिंट करें।

इसी तरह के प्रभाव को प्राप्त करने का एक और तरीका यह है कि आप अपने पैटर्न को खाली स्ट्रिंग से मिलान करने के लिए संशोधित करें। उदाहरण के लिए, यदि आप खोज का उपयोग कर रहे हैं, तो इसके बजाय rg fooका उपयोग करके खोज की rg "^|foo"गई प्रत्येक फ़ाइल में प्रत्येक पंक्ति का उत्सर्जन होगा, लेकिन केवल फू की घटनाओं को हाइलाइट किया जाएगा। यह ध्वज पैटर्न को संशोधित करने की आवश्यकता के बिना समान व्यवहार को सक्षम करता है।


1

GNU grep के लिए ऐसा करने का एक बहुत आसान तरीका है, लेकिन मुझे नहीं लगता कि यह पोर्टेबल है (यानी, BSD grep):

एक पाइप में:

cat <file> | grep --color=always -z <query>

एक फ़ाइल पर:

grep --color=always -z <query> <file>

यहां साइरस के जवाब का श्रेय जाता है


1
यह उतना अच्छा जवाब नहीं है जितना आप (और साइरस) सोचते हैं। इसमें संपूर्ण फ़ाइल को एक पंक्ति के रूप में मानने का प्रभाव है। इसलिए, (1) यदि फ़ाइल बहुत बड़ी है, वहाँ स्मृति से बाहर चल रहा है की संभावना हो सकती है, और (2) यदि फ़ाइल पैटर्न शामिल नहीं है सब पर है, तो कुछ भी नहीं उत्पादन किया जाएगा। और तुम सही हो; यह सार्वभौमिक रूप से उपलब्ध नहीं है। (लेकिन फिर से, मानक भी --colorनहीं है ।)
जी-मैन

इस पर grep का कौन सा संस्करण समर्थित है? 2.5.4 grep पर, -z उपलब्ध नहीं लगता है ...
एलेक्स

1

अब तक दिए गए उत्तरों में से कोई भी एक पोर्टेबल समाधान प्रदान नहीं करता है।

यहाँ एक पोर्टेबल है 1 खोल समारोह मैं पहले से ही तैनात डुप्लिकेट सवाल है कि गैर मानक उपकरण या के साथ प्रदान की गैर मानक एक्सटेंशन की आवश्यकता नहीं है के रूप में एक बंद में perl, ack, ggrep, gsed, bashऔर पसंद है, लेकिन केवल एक POSIX खोल और POSIX अनिवार्य उपयोगिताओं की जरूरत है sedऔर printf:

grepc()
{
  pattern=$1
  shift
  esc=$(printf "\033")
  sed 's"'"$pattern"'"'$esc'[32m&'$esc'[0m"g' "$@"
}

आप इसे इस तरह से उपयोग कर सकते हैं:

grepc string_to_search [file ...]

हाइलाइट कलर को इन कमांड कोड में से एक का उपयोग करके एडजस्ट किया जा सकता है।

30m black
31m red
33m yellow
34m blue
35m magenta
36m cyan
37m white
7m reverse video

1 जब तक आपका टर्मिनल एएनएसआई रंगों से बचने के दृश्यों का समर्थन करता है।


0

एक sedसंस्करण, दोनों पर काम करता है bashऔर ash

#highlight
hsed(){
    local pattern="$1"
    shift
    local r=`echo -e '\e'[31m`
    local c=`echo -e '\e'[0m`
    sed "s:${pattern//:/\:}:$r\0$c:g" "$@"
}

0

ओपी ने पूछा grep, और वह वही है जो मैं जानता हूं ; लेकिन sedरिकॉर्ड के लिए, किसी समस्या को हल करने के लिए कड़ी मेहनत करने के बाद , यहाँ इसके साथ एक सरल समाधान दिया गया है:

sed $'s/main/\E[31m&\E[0m/g' testt.c

या

cat testt.c | sed $'s/main/\E[31m&\E[0m/g'

mainलाल रंग में रंगेगा।

  • \E[31m : लाल रंग का प्रारंभ क्रम
  • \E[0m : समाप्त रंग का निशान
  • & : मिलान पैटर्न
  • /g : सभी शब्द एक पंक्ति में, केवल पहले नहीं
  • $'string' बश तार में भागे हुए पात्रों की व्याख्या की गई है

Grep के बारे में , यह ^लाइन के $अंत ( लाइन के बजाय) का उपयोग करके भी काम करता है । उदाहरण:

egrep "^|main" testt.c

और बस इस पागल उर्फ ​​को दिखाने के लिए कि मुझे मत छोड़ो , आप खुले उद्धरण भी दे सकते हैं:

alias h='egrep -e"^|'
h main" testt.c
cat testt.c | h main"

सारा काम! :) चिंता मत करो अगर आप बोली को बंद करना भूल जाते हैं, तो बैश आपको "निरंतर लाइन चरित्र" के साथ याद रखेगा।

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