बहुरंगी ग्रीप


30

मैं प्रत्येक grep कमांड प्राप्त करने की कोशिश कर रहा हूं ताकि यह अलग रंग में परिणत हो सके। मैं इसे इस तरह से एक लाइन के साथ मैन्युअल रूप से कर सकता हूं:

ls -l GREP_COLORS='mt=01;32' grep c | GREP_COLORS='mt=01;31' grep o | GREP_COLORS='mt=01;34' grep n | GREP_COLORS='mt=01;36' grep f

हरेक cपात्र हरे रंग में और हर oपात्र लाल रंग में हाइलाइट किया जाएगा ... आदि।

इस उदाहरण को काम करने के लिए आपको यह सुनिश्चित करने की आवश्यकता होगी कि आपके पास हमेशा --color=alwaysआपके grep कमांड्स हों। मैंने इसे सेट किया है .bashrc इसलिए मेरे grep में हमेशा रंग होंगे:

export GREP_OPTIONS='--color=always'


जो मैं पूरा करने का प्रयास कर रहा हूं वह इस कार्यक्षमता को एक उपनाम के साथ लपेटने के लिए है, इसलिए मैं हर बार कॉल कर सकता हूं grepऔर GREP_COLORSहर बार एक अलग मूल्य रख सकता हूं । मुझे लगता है कि प्रत्येक नए पाइप के लिए कई गोले के विचार को समझें और मैं कुछ फाइलों (प्रत्येक रंग के लिए एक) का निर्माण करके इस पर आने की कोशिश कर रहा हूं, यह इंगित करने के लिए कि उनका उपयोग पहले ही किया जा चुका है।

मैंने कुछ प्रयास किए हैं लेकिन अजीब तरह से, यह "सबसे अच्छा" काम करने लगता है। मेरे पास यह है .bashrc:

alias mg="mygrep"
mygrep(){
    # define possible colors
    COLORS=("01;32" "01;31" "01;34" "01;36")
    COUNTER=0
    NUM=0
    # as long as the color has already been used, keep searching
    while [ -f /home/lior/Desktop/mygrep_$NUM ]; do
        # get a random index
        let NUM=`shuf --input-range=0-$(( ${#COLORS[*]} - 1 )) | head -1`
        wait ${!}
        $(( COUNTER+=1 ))
        if [ "$COUNTER" -ge ${#COLORS[@]} ]; then
            # remove all color locks
            rm /home/lior/Desktop/mygrep_*
            wait ${!}
        fi
    done
    # mark this color as used
    touch /home/lior/Desktop/mygrep_$NUM
    wait ${!}

    # lets go!
    GREP_COLORS="mt=${COLORS[$NUM]}" grep "$@"
}

मैं इस तरह से अन्य उपनाम का उपयोग कर रहा हूं:

ll | mg c | mg o | mg n | mg f

परिणाम काफी अच्छे हैं। हालांकि कुछ त्रुटियां हैं जो हर बार थोड़ी भिन्न होती हैं। यहाँ स्क्रीनशॉट के एक जोड़े हैं:

ऐसा लगता है जैसे शेल प्रत्येक पाइप कमांड के माध्यम से जाता है, पिछले फ़ंक्शन ने अभी तक इसे समाप्त नहीं किया है। यह उन फ़ाइलों को हटाने की कोशिश करता है जो किसी भी अधिक मौजूद नहीं हैं। मुझे यह भी पक्का नहीं है कि वे अन्य command not foundत्रुटियाँ कहाँ से आ रही हैं।

जैसा कि आप देख सकते हैं, मैंने कुछ waitआदेशों को फ़ाइल हेरफेर को पूरा करने की कोशिश करने के लिए रखा है, लेकिन यह बहुत अच्छी तरह से काम नहीं करता है। एक और चीज जो मैंने पहले ही आजमाई है वह साझा मेमोरी का उपयोग करना है /dev/shmलेकिन यह समान परिणाम प्राप्त करता है।

मैं कैसे परिणाम प्राप्त करना चाहूंगा?

ध्यान दें:

मैं उन उत्तरों की तलाश में हूं जो केवल grep कमांड को लपेटते हैं क्योंकि इसमें बहुत सारी कार्यक्षमता है जो मैं उपयोग करना चाहता हूं और पाइप के बीच अन्य तर्क डालने का इरादा रखता हूं, इसलिए मैं एक बार में सभी खोज शब्द प्रदान नहीं करना चाहता। मैं अन्य "grep जैसे" टूल की भी तलाश नहीं कर रहा हूं। @Terdon को क्षमा करें जिन्होंने पहले से ही एक भयानक पर्ल सुझाव पोस्ट किया है।


आपका पहला उदाहरण बचे हुए भाग में आपको जो समझा रहा है, उससे मेल नहीं खाता, सिर्फ कह रहा है।
बर्नहार्ड

@bernhard मुझे समझ में नहीं आ रहा है कि आपका क्या मतलब है .. मेरा इरादा पाइप का उपयोग करके एक बड़े कमांड के हिस्से के रूप में मेरे उपनाम का उपयोग करना है ... कृपया मुझे बताएं कि आप किस विरोधाभास की बात कर रहे हैं ...
Lix

मुझे लगा कि आप पाइप के बाहर भी अपने उपनाम का उपयोग करना चाहते हैं। किसी भी तरह, आपका पहला उदाहरण मेरे लिए काम नहीं करता है। क्या आपने कोशिश की alias mg="mygrep; grep"?
बर्नहार्ड

@ बर्नहार्ड - मैं एक ubuntu 12.04 बॉक्स पर काम कर रहा हूँ। मुझे आश्चर्य नहीं होगा अगर थोड़े से मतभेद थे ... मैंने आपके सुझाव की कोशिश की, इसके साथ समस्या यह है कि mygrep;यह अपने आप में एक नई कमांड में बदल जाता है और डेटा स्ट्रीम खो जाता है। आने वाले पाइप को lsपास करने के लिए mygrep;और नहीं पकड़ना होगा। कम से कम मैं इसे कैसे समझूं।
Lix

@ बर्नहार्ड - आह .. मुझे लगता है कि मुझे पता है कि यह आपके लिए काम क्यों नहीं किया। आपको यह सुनिश्चित करने की आवश्यकता है कि आपके पास --color=alwaysआपके सभी grep कमांड हैं। मैंने वह विश्व स्तर पर स्थापित किया है .bashrc। मैंने उसे पोस्ट में संपादित किया है।
Lix

जवाबों:


6

यहाँ एक अलग दृष्टिकोण है। मेरे पास एक छोटी सी पर्ल स्क्रिप्ट है जिसे मैंने पहले ही एक और उत्तर में पोस्ट किया है जो विभिन्न रंगों में उपयोगकर्ता द्वारा प्रदान किए गए पैटर्न को उजागर करेगा। स्क्रिप्ट का थोड़ा संशोधित संस्करण कार्य करेगा grep:

#!/usr/bin/env perl
use Getopt::Std;
use strict;
use Term::ANSIColor; 

my %opts;
getopts('hic:l:',\%opts);
    if ($opts{h}){
      print<<EoF; 
Use -l to specify the pattern(s) to highlight. To specify more than one 
pattern use commas. 

-l : A Perl regular expression to be colored. Multiple expressions can be
     passed as comma separated values: -l foo,bar,baz
-i : makes the search case sensitive
-c : comma separated list of colors;

EoF
      exit(0);
    }

my $case_sensitive=$opts{i}||undef;
my @color=('bold red','bold blue', 'bold yellow', 'bold green', 
       'bold magenta', 'bold cyan', 'yellow on_blue', 
       'bright_white on_yellow', 'bright_yellow on_red', 'white on_black');
if ($opts{c}) {
   @color=split(/,/,$opts{c});
}
my @patterns;
if($opts{l}){
     @patterns=split(/,/,$opts{l});
}
else{
    $patterns[0]='\*';
}

# Setting $| to non-zero forces a flush right away and after 
# every write or print on the currently selected output channel. 
$|=1;

while (my $line=<>) 
{ 
    my $want=0;
    for (my $c=0; $c<=$#patterns; $c++){
    if($case_sensitive){
        if($line=~/$patterns[$c]/){
           $line=~s/($patterns[$c])/color("$color[$c]").$1.color("reset")/ge;
           $want++;
        }
    }
    else{
        if($line=~/$patterns[$c]/i){
          $line=~s/($patterns[$c])/color("$color[$c]").$1.color("reset")/ige;
          $want++;
        }
      }
    }
print STDOUT $line if $want>0;
}

यदि आप उस स्क्रिप्ट को cgrepअपने रूप में कहीं PATHऔर सहेजते हैं और इसे निष्पादन योग्य बनाते हैं, तो आप अधिकतम 10 अलग-अलग पैटर्न निर्दिष्ट कर सकते हैं, जिनमें से प्रत्येक को एक अलग रंग में मुद्रित किया जाएगा:

यहां छवि विवरण दर्ज करें

$ cgrep -h
Use -l to specify the pattern(s) to highlight. To specify more than one 
pattern use commas. 

-l : A Perl regular expression to be colored. Multiple expressions can be
     passed as comma separated values: -l foo,bar,baz
-i : makes the search case sensitive
-c : comma separated list of colors;

5

grepपाइप में प्रत्येक आह्वान एक अलग शेल में चलता है, इसलिए आपको उनके बीच कुछ राज्य पारित करने की आवश्यकता होगी। निम्न समाधान एक क्रैडल तरीका है जो उस फाइल को संभालता है जो कलर इंडेक्स और एक लॉक फाइल रखता है जो यह सुनिश्चित करता है कि एक साथ कॉल एक ही मूल्य को न पढ़ें:

#!/usr/bin/env bash
color_index_file=~/.gitcolor
color_index_lock_file=/tmp/$(basename $0)

colors=()
for index in {31..34}
do
    colors+=("01;$index")
done

until mkdir "$color_index_lock_file" 2>/dev/null
do
    :
done

color_index=$(($(cat "$color_index_file" || echo 0) + 1))

if [[ $color_index -ge ${#colors[@]} ]]
then
    color_index=0
fi

printf "$color_index" > "$color_index_file"
rmdir "$color_index_lock_file"

GREP_COLORS="mt=01;${colors[$color_index]}" grep --color=always "$@"

परीक्षण यह मानते हुए कि आपने अपनी कॉपी अपने नाम कर ली है cgrepऔर उसे अपने पास रख लिया है PATH:

echo foobarbaz | cgrep foo | cgrep bar | cgrep baz

केवल चर जो वास्तव में बनाए रखने की आवश्यकता है COLOR_INDEXऔर हैं GREP_COLORS। मैंने सफलता के बिना फ़ंक्शन के अंत में इन्हें निर्यात करने का प्रयास किया। क्या आपका आशय यही था? बस export VAR, ठीक है?
लीक्स

ओह - और हाँ .. मूर्ख टाइपो वहाँ के साथ COLOR_TOGGLE। इसे पकड़ने के लिए धन्यवाद :)
Lix

1
@ l0b0 निर्यात मेरे लिए या तो काम नहीं करता है, अब तक के लिए इसे कम करना है जब तक कि यह वास्तव में सवाल का जवाब नहीं देता है।
बर्नहार्ड

@ बर्नहार्ड क्या यह आपके लिए काम करता है?
l0b0

आपके सहयोग के लिए धन्यवाद! मैंने आपके grep "$@"सुझाव को शामिल कर लिया है - जो कि फ़ंक्शन को चलाने के लिए उपनाम को छांटता है और फिर grep करता है।
Lix

1

यदि आप नियमित अभिव्यक्ति के साथ अच्छे हैं, तो आप grc और grcat की जांच करना चाहते हैं। grc को grcat कहते हैं।

grcat कॉन्फ़िगरेशन फ़ाइलों का उपयोग करता है जहां आप प्रत्येक रंग में प्रदर्शित होने वाले पाठ से मेल खाने के लिए नियमित अभिव्यक्ति जोड़ सकते हैं। इसमें कई अन्य विकल्प भी हैं। यह सिस्टम लॉग फ़ाइलों को रंग देने में चूक करता है।

आपकी अंतिम स्क्रिप्ट के लिए आपके मन में क्या है, इस पर निर्भर करते हुए, आप केवल एक कमांड के साथ अपने आउटपुट को रंगीन करने में सक्षम हो सकते हैं।

चाल आपके डेटा स्रोत में प्रत्येक "फ़ील्ड" के लिए रीग्क्स को सही ढंग से निर्दिष्ट कर रही है। यह बहुत आसान होगा यदि आपका डेटा संरचना में अपेक्षाकृत समान है।

पिछली बार जब मैंने इसकी कोशिश की थी, तो मैं बहुत दूर नहीं था, लेकिन हो सकता है कि मैं इस पर एक और जाऊं क्योंकि मैं उस समय की तुलना में रेक्सक्स में थोड़ा बेहतर हूं।

टुट कमांड भी है जिसका उपयोग आपके टर्मिनल डिवाइस पर सीधे सूचना (जैसे रंग परिवर्तन) भेजने के लिए किया जा सकता है।

दोनों दृष्टिकोण नीचे पोस्ट द्वारा कवर किए गए हैं। यह खोज कमांड के बारे में बात करता है, लेकिन इसे किसी भी कमांड के आउटपुट पर लागू किया जा सकता है।

रंगीन FIND आउटपुट?

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