Çok renkli Grep


30

Her grep komutunun farklı bir renkle sonuçlandığını vurgulamaya çalışıyorum. Böyle bir çizgiyle manuel olarak yapabilirim:

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

Her ckarakter yeşil renkle vurgulanır ve her okarakter kırmızı renkle vurgulanır, vb.

Bu örneğin çalışması için, daima --color=alwaysgrep komutlarınızda olmasını sağlamanız gerekir . Bunu ben ayarlıyorum bu .bashrc yüzden grep her zaman renkleri olacak:

export GREP_OPTIONS='--color=always'


Başarmaya çalıştığım şey, bu işlevselliği bir takma adla sarmak, böylece her defasında arayabilir grepve farklı bir GREP_COLORSdeğere sahip olabilirim . Her yeni borulu grep için çoklu mermilerin dikkatini anlıyorum ve zaten kullanıldıklarını belirtmek için bazı dosyalar (her renk için bir tane) oluşturarak bunu tekrar gündeme getirmeye çalışıyorum.

Bazı girişimler yaptım ama garip bir şekilde, bu "en iyi" işe yaramış gibi görünüyor. Bu benim içinde var .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 "$@"
}

Bu takma adı şöyle kullanıyorum:

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

Sonuçlar oldukça iyi. Ancak her seferinde biraz farklı olan bazı hatalar var. İşte birkaç ekran görüntüsü:

Kabuk her boru komutundan geçerken, önceki işlev henüz çalışmasını tamamlamadı. Artık bulunmayan dosyaları kaldırmaya çalışıyor. Diğer command not foundhataların nereden geldiğinden emin değilim .

Gördüğünüz gibi wait, dosya manipülasyonunun tamamlanmasına izin vermek için bazı komutlar koydum, ancak bu çok iyi çalışmıyor gibi görünüyor. Zaten denedim başka bir şey paylaşılan hafıza kullanmak, /dev/shmancak benzer sonuçlar vermiştir.

İstediğim sonuçları almaya nasıl devam edebilirim?

Not:

Grep komutunu, sadece kullanmak istediğim ve borular arasına başka bir mantık eklemek istediğim için çok fazla işlevselliğe sahip olduğu için cevapları arıyorum, bu nedenle tüm arama terimlerini bir kerede sağlamak istemiyorum. Ayrıca diğer "grep like" araçlarını da istemiyorum. Müthiş bir perl önerisi yayınlayan @ terdon'a üzgünüm .


İlk örneğiniz sadece söyleyerek geri kalan kısımda açıkladığınızla uyuşmuyor.
Bernhard

@bernhard Ne demek istediğini anlamadım .. Niyetim, takma adımı borular kullanarak daha büyük bir komutun parçası olarak kullanmak ... Lütfen bana hangi çelişkiden bahsettiğini söyle ...
Lix

Takma adınızı borular dışında da kullanmak istediğinizi düşündüm. Her neyse, ilk örneğiniz benim için çalışmıyor. Denedin alias mg="mygrep; grep"mi
Bernhard

@Bernhard - Bir ubuntu 12.04 kutusu üzerinde çalışıyorum. Küçük farklılıklar olsaydı şaşırmam… Önerinizi denedim, sorun şu ki mygrep;, başlı başına yeni bir komuta dönüşüyor ve veri akışı kayboluyor. Oradan gelen boru lssıyrılmayarak mygrep;geçilirdi. En azından ben böyle anlıyorum.
Lix

@ Bernhard - Ah .. Sanırım neden senin için işe yaramadığını biliyorum. --color=alwaysTüm grep komutlarınızda olduğundan emin olmanız gerekir . Bunu global olarak benim yerime koydum .bashrc. Bunu yazıya yazdım.
Lix

Yanıtlar:


6

İşte farklı bir yaklaşım. Kullanıcının sağladığı modelleri farklı renklerde vurgulayabilen başka bir cevabında yayınladığım küçük bir Perl betiğim var . Komut dosyasının biraz değiştirilmiş bir sürümü şöyle davranır 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;
}

Bu betiği cgrepsizin yerinizde bir yere kaydeder PATHve yürütülebilir hale getirirseniz, her biri farklı bir renkte yazdırılacak en fazla 10 farklı desen belirleyebilirsiniz:

görüntü tanımını buraya girin

$ 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

grepBir boruya yapılan her çağrı ayrı bir kabuk içinde çalışır, bu nedenle aralarında bir durum geçirmeniz gerekir. Aşağıdaki çözüm, renk indeksini tutan bir dosya ve eşzamanlı çağrıların aynı değeri okumamasını sağlayan bir kilit dosyası ile baş etmenin kaba bir yoludur:

#!/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 "$@"

Kopyanızı adlandırdığınızı cgrepve üzerine yazdığınızı varsayarak test edin PATH:

echo foobarbaz | cgrep foo | cgrep bar | cgrep baz

Gerçekten korunması gereken tek değişkenler COLOR_INDEXve GREP_COLORS. Bunları fonksiyon sonunda başarılı olmadan vermeyi denedim. Demek istediğin bu muydu? Basitçe sahip olmak export VAR, değil mi?
Lix

Oh - ve evet .. ile aptal yazım hatası orada COLOR_TOGGLE.
Yakaladığınız

1
@ l0b0 Verme işlemi de benim için çalışmıyor, soruyu gerçekten yanıtlayana kadar şimdilik oy vermemelisiniz.
Bernhard

@Bernhard Bu sizin için çalışıyor mu?
l0b0

Giriş için teşekkürler! Ben senin dahil ettik grep "$@"fonksiyonu çalıştırmak ve ardından grep takma dizildi - öneri.
Lix

1

Düzenli ifadeler konusunda iyiyseniz, grc ve grcat adreslerini incelemek isteyebilirsiniz. grc grcat'i çağırır.

grcat, her renkte görüntülenecek metni eşleştirmek için normal ifadeler ekleyebileceğiniz yapılandırma dosyalarını kullanır. Aynı zamanda başka birçok seçeneğe sahiptir. Sistem günlük dosyalarını renklendirme varsayılandır.

Son senaryonuz için aklınızdakilere bağlı olarak, çıktınızı yalnızca bir komutla renklendirebilirsiniz.

Hile veri kaynağınızdaki her "alan" için regex'leri doğru şekilde belirtmektir. Verileriniz yapıda göreceli olarak aynı ise, bu çok daha kolay olacaktır.

En son denediğimde çok fazla ileri gitmedim, ama bir başkasına gidiyorum çünkü regex'lerde o zaman olduğundan daha iyiyim.

Doğrudan terminal cihazınıza bilgi göndermek için kullanılabilecek bir tput komutu da vardır (renk değişiklikleri gibi).

Her iki yaklaşım da aşağıdaki posta tarafından ele alınmaktadır. Find komutundan bahseder, ancak herhangi bir komutun çıktısına uygulanabilir.

Renkli FIND çıkışı?

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.