staging.inyokaproject.org

grep farbig + zusätzliches grep = keine Farbe

Status: Gelöst | Ubuntu-Version: Ubuntu 14.04 (Trusty Tahr)
Antworten |

frank-w

Anmeldungsdatum:
30. September 2008

Beiträge: 419

Hallo,

ich nutze öfters "grep -Rn 'irgendwas' ." welches mir in sämtlichen Dateien nach "irgendwas" sucht und Dateinamen+Zeilennummer+gesuchten Begriff schön farbig anzeigt. wenn ich nun ein weiteres grep anhänge via pipe, um die gefundenen Zeilen weiter einzuschränken (z.B. weil ich nur header-Dateien haben möchte) geht die Farbkennzeichnung wieder verloren.

1
grep -Rn 'function' . | grep '\.h:'

gibt es eine Möglichkeit dies zu verhindern?

als workaround habe ich gerade das gefunden: https://forum.ubuntuusers.de/post/8912421/

1
2
shopt -s globstar
grep -Rn 'cat.*function' **/*.h

trotzdem wäre es interessant, ob man grep irgendwie veranlassen könnte, die farbliche Formatierung beizubehalten

Gruß Frank

misterunknown Team-Icon

Ehemalige
Avatar von misterunknown

Anmeldungsdatum:
28. Oktober 2009

Beiträge: 4403

Das geht so mit der Option color. Wenn diese auf always gesetzt ist, werden auch Markierungen von vorhergehenden grep-Befehlen beibehalten:

grep --color=always -ri "127.0.0.1" /etc/ | grep --color=always localhost

Du kannst dir auch einen Alias bauen, beispielsweise mit ein paar Zeilen in deiner ~/.bashrc:

export MYGREPOPTS="--color=always"
alias grep='grep $MYGREPOPTS'

Hinweis: Es gab mal eine Option GREP_OPTIONS, welche von grep ausgewertet wurde. Allerdings ist diese veraltet – man soll stattdessen einen Alias oder ein Skript verwenden.

track

Avatar von track

Anmeldungsdatum:
26. Juni 2008

Beiträge: 7174

Und noch ein kleiner Hinweis: die "Farbe" wird in Wirklichkeit durch eingefügte ANSI-Codes erzeugt.

Solltest Du also im 2. grep etwas suchen, das eine Farbgrenze berührt, musst Du das berücksichtigen:

track@track:~$ echo 12345  |  grep --color=always 23
12345
track@track:~$ echo 12345  |  grep --color=always 23  |  hd
00000000  31 1b 5b 30 31 3b 33 31  6d 1b 5b 4b 32 33 1b 5b  |1.[01;31m.[K23.[|
00000010  6d 1b 5b 4b 34 35 0a                              |m.[K45.|
00000017
track@track:~$ echo 12345  |  grep --color=always 23  |  grep 34                    # das geht also nicht
track@track:~$ echo 12345  |  grep --color=always 23  |  grep 3......4              # aber so geht es
12345 

LG,

track

frank-w

(Themenstarter)

Anmeldungsdatum:
30. September 2008

Beiträge: 419

so ganz funktioniert es nicht

1
grep -Rn 'function' . | grep --color=always '\.h:'

der erste teil macht - den Dateinamen lila - die Zeilennummer grün - den suchtext rot

mit dem zweiten grep ist dann nur der neue Suchtext rot. interesanterweise funktioniert er aber, obwohl dieser wie von Track angemerkt auf einer Farbgrenze liegt. Scheinbar macht grep erst den "Farbreset" matcht neu und coloriert den neuen Match

1
2
frank@Frank-Laptop:/media/data_ext/kernel_4.14/linux-stable$ type grep
grep ist ein Alias von »grep --color=auto«.

habe jetzt zur Sicherheit den alias mal vermieden durch /bin/grep statt nur grep...ist aber gleiches Phänomen

seahawk1986

Anmeldungsdatum:
27. Oktober 2006

Beiträge: 11278

grep schaltet soweit ich weiß die color-Option automatisch ab, wenn die Ausgabe eine Pipe ist (z.B. https://stackoverflow.com/questions/2327191/preserve-colouring-after-piping-grep-to-grep).

Ich würde Source-Code lieber mit einem Tool wie The Silver Searcher (oder ripgrep) durchsuchen, damit kann man leicht die Suche auf Header-Dateien einschränken, das sieht dann wie im Anhang aus.

Anhang

track

Avatar von track

Anmeldungsdatum:
26. Juni 2008

Beiträge: 7174

frank-w schrieb:

1
grep -Rn 'function' . | grep --color=always '\.h:'

der erste teil macht - den Dateinamen lila - die Zeilennummer grün - den suchtext rot

mit dem zweiten grep ist dann nur der neue Suchtext rot. interesanterweise funktioniert er aber, obwohl dieser wie von Track angemerkt auf einer Farbgrenze liegt.

Irrtum. - Dein 2. Suchausdruck liegt zwar an einer Farbgrenze, aber der ANSI-Kram kommt erst nach dem Dateinamen. Also kein Konflikt. Und außerdem:

Scheinbar macht grep erst den "Farbreset" matcht neu und coloriert den neuen Match

Nee - denn wie seahawk1986 schon sagte: bei dem 1. grep ist die Farbe ausgeschaltet, denn Du hast ihm ja kein "--color=always" spendiert !

LG,

track

frank-w

(Themenstarter)

Anmeldungsdatum:
30. September 2008

Beiträge: 419

track schrieb:

frank-w schrieb:

mit dem zweiten grep ist dann nur der neue Suchtext rot. interesanterweise funktioniert er aber, obwohl dieser wie von Track angemerkt auf einer Farbgrenze liegt.

Irrtum. - Dein 2. Suchausdruck liegt zwar an einer Farbgrenze, aber der ANSI-Kram kommt erst nach dem Dateinamen. Also kein Konflikt.

Dateiname ist dorch lila und der doppelpunkt mit Zeilennummer ist grün ⇒ "\.h:" beides drin ⇒ Farbgrenze

Scheinbar macht grep erst den "Farbreset" matcht neu und coloriert den neuen Match

Nee - denn wie seahawk1986 schon sagte: bei dem 1. grep ist die Farbe ausgeschaltet, denn Du hast ihm ja kein "--color=always" spendiert !

beim ersten grep ist der alias aktiv, welcher "--color=auto" enthält...aber

ich habe es gerade probiert...wenn ich beim ersten grep --color=always nehme, wird die Farbe nicht abgeschaltet (scheinbar nur bei color=auto ,wie auch im angehakten Beitrag [108] im Link von seahawks link). Hier fällt dann auch gleich die Sache mit der Farbgrenze auf...es werden nur noch Zeilen angezeigt, wo das .h: nicht teil des von grep erzeugten Dateinamen (also .h: innerhalb der Datei) ist

kann man die ascii-farb-definietion für das suchen beim grep irgendwie aussparen (wie bei tracks beitrag nur halt kürzer als die 6 Wildcard-Punkte)? habs mal zum test mit ".{6}" probiert, aber scheint nicht so zu funktionieren

rklm Team-Icon

Projektleitung

Anmeldungsdatum:
16. Oktober 2011

Beiträge: 13242

seahawk1986 schrieb:

grep schaltet soweit ich weiß die color-Option automatisch ab, wenn die Ausgabe eine Pipe ist (z.B. https://stackoverflow.com/questions/2327191/preserve-colouring-after-piping-grep-to-grep).

Das liegt nur daran, dass grep auf Ubuntu-Systemen standardmäßig ein Alias ist:

1
2
$ type grep
grep is aliased to `grep --color=auto'

Ansonsten würden nie Farben gesetzt werden.

Ich würde nach einem Suchausdruck fahnden, der die Sache mit einem (e)grep erledigt. Im schlimmsten Fall muss man mit Kombinationen arbeiten:

1
egrep -Rn 'function.*\.h:|\.h:.*function'

Wenn Du weißt, dass "function" immer vor ".h:" steht oder umgekehrt, kannst Du eine der Alternativen weglassen.

Der Punkt am Ende wird übrigens bei -R nicht benötigt.

frank-w

(Themenstarter)

Anmeldungsdatum:
30. September 2008

Beiträge: 419

Hallo,

das .h ist der Dateiname den grep im ersten durchlauf erzeugt, somit lässt sich das nicht (so) kombinieren. ich glaube in dem Fall ist es mit dem globstar-workaround der sauberste Weg. aber für andere Fälle ist dann --color=always sinnvoll

Danke an alle

seahawk1986

Anmeldungsdatum:
27. Oktober 2006

Beiträge: 11278

frank-w schrieb:

ich glaube in dem Fall ist es mit dem globstar-workaround der sauberste Weg.

Bei grep funktioniert so etwas wie grep -Rn suchwort **/*.h auch ohne dass die globstar-Option gesetzt ist:

me@VDR:~/src/vdr-2.2.0$ shopt | grep globstar
globstar       	off
me@VDR:~/src/vdr-2.2.0$ grep -Rn thread **/*.h
libsi/util.h:18:#include <pthread.h>
libsi/util.h:101:      pthread_mutex_t mutex;
libsi/util.h:103:      pthread_t locked; 

rklm Team-Icon

Projektleitung

Anmeldungsdatum:
16. Oktober 2011

Beiträge: 13242

seahawk1986 schrieb:

frank-w schrieb:

ich glaube in dem Fall ist es mit dem globstar-workaround der sauberste Weg.

Da Du schon Dateien filtern willst, ist der sauberste Web über find - das spart auch unnötiges Lesen von Dateien. Man filtert am besten immer erst nach dem Namen und Typ und dann nach Inhalten. Du hast das genau anders herum gemacht. Also, man macht das so:

1
find -type f -name '*.h' -exec fgrep -Hn --color=auto function {} +

Bei grep funktioniert so etwas wie grep -Rn suchwort **/*.h auch ohne dass die globstar-Option gesetzt ist:

Das stimmt nicht: zum einen hat das Globbing überhaupt nichts mit dem Kommando zu tun, bei dessen Aufruf man das verwendet. Zum anderen funktioniert die rekursive Mustererkennung nur, wenn "globstar" eingeschaltet ist:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
$ mkdir -p a/b/c/d/e/f
$ shopt globstar
globstar       	on
$ printf '%s\n' a/**/*
a/b
a/b/c
a/b/c/d
a/b/c/d/e
a/b/c/d/e/f
$ shopt -u globstar
$ shopt globstar
globstar       	off
$ printf '%s\n' a/**/*
a/b/c
me@VDR:~/src/vdr-2.2.0$ shopt | grep globstar
globstar       	off
me@VDR:~/src/vdr-2.2.0$ grep -Rn thread **/*.h
libsi/util.h:18:#include <pthread.h>
libsi/util.h:101:      pthread_mutex_t mutex;
libsi/util.h:103:      pthread_t locked; 

Du siehst hier kein besonders Matching von "**" sondern nur das normale, das "*" macht (s.o.).

frank-w

(Themenstarter)

Anmeldungsdatum:
30. September 2008

Beiträge: 419

da hast du schon Recht, dass man erst die Dateien sucht und dann erst den Inhalt...ist aber in dem Fall "historisch gewachsen", da ich kurz und knapp nach einem Funktionsnamen gesucht habe (kurz und ausreichend schnell mit grep) und wenns mir zuviele Treffer waren dann nachträglich filtern wollte...

die find-Zeile ist halt wesentlich länger, mal schauen, ob ich mir da nen alias/script baue, um das schneller griffbeerit zu haben ☺

rklm Team-Icon

Projektleitung

Anmeldungsdatum:
16. Oktober 2011

Beiträge: 13242

frank-w schrieb:

die find-Zeile ist halt wesentlich länger, mal schauen, ob ich mir da nen alias/script baue, um das schneller griffbeerit zu haben ☺

Denk drank, dass Shell-Funktionen auch eine Alternative sind! Das kommt insbesondere hier zum tragen, weil Du ja nicht einfach hinten etwas an die Kommandozeile anhängen willst, sondern mittendrin. Also, Du könntest so etwas in der ~/.bash_alias unterbringen:

1
2
3
sufu() {
  find -type f -name '*.h' -exec fgrep -Hn --color=auto "$1" {} +
}

Dann sagst Du einfach sufu printNonsense und er findet Dir das. ☺

frank-w

(Themenstarter)

Anmeldungsdatum:
30. September 2008

Beiträge: 419

alias war falsch...meinte schon die Shellfunktion ☺

werf ich ja beides in die .bashrc

danke, dass du mir schon eine gebastelt hast

Antworten |