GNU/Linux >> LINUX-Kenntnisse >  >> Linux

10 praktische Grep-Befehlsbeispiele für Entwickler

Vor kurzem habe ich begonnen, mit zu arbeiten Asciidoctor.js und on das Projekt Asciidoctor.js-pug und Asciidoctor-templates.js.

Es ist nicht immer einfach, sofort effektiv zu sein, wenn Sie zum ersten Mal in eine Codebasis mit mehreren tausend Zeilen eintauchen. Aber meine Geheimwaffe, um mich durch so viele Codezeilen zurechtzufinden, ist grep Werkzeug.

Ich werde Ihnen anhand von Beispielen zeigen, wie Sie den grep-Befehl unter Linux verwenden.

Nützliche Beispiele aus dem wirklichen Leben für die grep-Befehle in Linux

Wenn Sie in den man schauen , sehen Sie diese kurze Beschreibung für grep Werkzeug:"Zeilen drucken, die einem Muster entsprechen."

Lassen Sie sich jedoch nicht von dieser bescheidenen Definition täuschen:grep ist eines der nützlichsten Werkzeuge in der Unix-Toolbox und es gibt unzählige Gelegenheiten, es zu verwenden, sobald Sie mit Textdateien arbeiten.

Es ist immer besser, Beispiele aus der Praxis zu haben, um zu lernen, wie die Dinge funktionieren. Daher werde ich den Asciidoctor.js-Quellbaum verwenden, um einige der grep zu veranschaulichen Fähigkeiten.

Sie können diesen Quellbaum von GitHub herunterladen, und wenn Sie möchten, können Sie sich sogar denselben Änderungssatz ansehen, den ich beim Schreiben dieses Artikels verwendet habe. Dadurch wird sichergestellt, dass Sie absolut identische Ergebnisse wie im Rest dieses Artikels erhalten:

git clone https://github.com/asciidoctor/asciidoctor.js
cd asciidoctor.js
git checkout v1.5.6-rc.1

1. Finde alle Vorkommen einer Zeichenkette (grundlegende Verwendung)

Asciidoctor.js unterstützt die Nashorn-JavaScript-Engine für die Java-Plattform. Ich kenne Nashorn nicht, also könnte ich die Gelegenheit nutzen, um mehr darüber zu erfahren, indem ich die Projektteile erkunde, die auf diese JavaScript-Engine verweisen.

Als Ausgangspunkt habe ich überprüft, ob es in package.json einige Einstellungen in Bezug auf Nashorn gibt Datei, die die Projektabhängigkeiten beschreibt:

[email protected]:~$ grep nashorn package.json
    "test": "node npm/test/builder.js && node npm/test/unsupported-features.js && node npm/test/jasmine-browser.js && node npm/test/jasmine-browser-min.js && node npm/test/jasmine-node.js && node npm/test/jasmine-webpack.js && npm run test:karmaBrowserify && npm run test:karmaRequirejs && node npm/test/nashorn.js",

Ja, anscheinend gab es einige Nashorn-spezifische Tests. Lassen Sie uns das also ein wenig genauer untersuchen.

2. Suche ohne Berücksichtigung der Groß-/Kleinschreibung in einem Dateisatz

Nun möchte ich mir die Dateien aus ./npm/test/ genauer ansehen Verzeichnis, in dem Nashorn ausdrücklich erwähnt wird.

Eine Suche ohne Berücksichtigung der Groß-/Kleinschreibung (-i Option) ist hier wahrscheinlich besser, da ich beide Verweise auf nashorn finden muss und Nashorn (oder jede andere Kombination aus Groß- und Kleinbuchstaben):

[email protected]:~$ grep -i nashorn npm/test/*.js
npm/test/nashorn.js:const nashornModule = require('../module/nashorn');
npm/test/nashorn.js:log.task('Nashorn');
npm/test/nashorn.js:nashornModule.nashornRun('jdk1.8.0');

In der Tat war die Unterscheidung zwischen Groß- und Kleinschreibung hier nützlich. Sonst hätte ich das require('../module/nashorn') übersehen Erklärung. Zweifellos sollte ich diese Datei später genauer untersuchen.

3. Finden Sie alle nicht übereinstimmenden Dateien

Übrigens gibt es einige nicht-Nashorm-spezifische Dateien in npm/test/ Verzeichnis? Um diese Frage zu beantworten, können wir die Option „nicht übereinstimmende Dateien drucken“ von grep (-L Option):

sh$ grep -iL nashorn npm/test/*
npm/test/builder.js
npm/test/jasmine-browser-min.js
npm/test/jasmine-browser.js
npm/test/jasmine-node.js
npm/test/jasmine-webpack.js
npm/test/unsupported-features.js

Beachten Sie, wie mit dem -L Option die Ausgabe von grep wurde geändert, um nur Dateinamen anzuzeigen. Keine der oben genannten Dateien enthält also die Zeichenfolge „nashorn“ (egal in welchem ​​Fall). Das bedeutet nicht, dass sie nicht irgendwie mit dieser Technologie verwandt sind, aber zumindest sind die Buchstaben „n-a-s-h-o-r-n“ nicht vorhanden.

4. Muster in versteckten Dateien und rekursiv in Unterverzeichnissen finden

Die letzten beiden Befehle verwendeten ein Shell-Glob-Muster, um die Liste der zu untersuchenden Dateien an grep zu übergeben Befehl.

Dies hat jedoch einige inhärente Einschränkungen:Der Stern (* ) stimmt nicht mit versteckten Dateien überein. Es wird auch nicht mit Dateien übereinstimmen, die (eventuell) in Unterverzeichnissen enthalten sind.

Eine Lösung wäre, grep zu kombinieren mit dem find-Befehl, anstatt sich auf ein Shell-Glob-Muster zu verlassen:

# This is not efficient as it will spawn a new grep process for each file
[email protected]:~$ find npm/test/ -type f -exec grep -iL nashorn \{} \;
# This may have issues with filenames containing space-like characters
[email protected]:~$ grep -iL nashorn $(find npm/test/ -type f)

Wie ich es als Kommentar zum obigen Codeblock erwähnt habe, hat jede dieser Lösungen Nachteile.

In Bezug auf Dateinamen, die Leerzeichen enthalten, lasse ich Sie den grep -z untersuchen Option which, kombiniert mit -print0 Option des find Befehl, kann dieses Problem abmildern. Zögern Sie nicht, den Kommentarbereich am Ende dieses Artikels zu nutzen, um Ihre Ideen zu diesem Thema mitzuteilen!

Dennoch würde eine bessere Lösung die „rekursive“ (-r )-Option von grep . Mit dieser Option geben Sie auf der Befehlszeile den Stamm Ihres Suchbaums (das Startverzeichnis) anstelle der expliziten Liste der zu untersuchenden Dateinamen an.

Mit dem -r Option durchsucht grep alle Dateien im angegebenen Verzeichnis, einschließlich versteckter, und dann rekursiv in ein beliebiges Unterverzeichnis absteigend:

[email protected]:~$ grep -irL nashorn npm/test/npm/
npm/test/builder.js
npm/test/jasmine-browser-min.js
npm/test/jasmine-browser.js
npm/test/jasmine-node.js
npm/test/jasmine-webpack.js
npm/test/unsupported-features.js

Mit dieser Option könnte ich meine Erkundung auch eine Ebene höher beginnen, um zu sehen, dass es Nicht-npm-Tests gibt, die auch auf Nashorn abzielen:

[email protected]:~$ grep -irL nashorn npm/

Ich lasse Sie diesen Befehl selbst testen, um das Ergebnis zu sehen. Aber als Hinweis kann ich sagen, dass Sie viele weitere passende Dateien finden sollten!

5. Filtern von Dateien nach ihrem Namen (unter Verwendung regulärer Ausdrücke)

Es scheint also einige Nashorn-spezifische Tests in diesem Projekt zu geben. Da Nashorn Java ist, wäre eine weitere Frage, die gestellt werden könnte, "Gibt es einige Java-Quelldateien im Projekt, die Nashorn ausdrücklich erwähnen?" .

Abhängig von der Version von grep Sie verwenden, gibt es mindestens zwei Lösungen, um diese Frage zu beantworten.

Die erste ist die Verwendung von grep Um alle Dateien zu finden, die das Muster „nashorn“ enthalten, leiten Sie die Ausgabe dieses ersten Befehls an ein zweites grep weiter Instanz, die Nicht-Java-Quelldateien herausfiltert:

[email protected]:~$ grep -ir nashorn ./ | grep "^[^:]*\.java"
./spec/nashorn/AsciidoctorConvertWithNashorn.java:public class AsciidoctorConvertWithNashorn {
./spec/nashorn/AsciidoctorConvertWithNashorn.java:    ScriptEngine engine = engineManager.getEngineByName("nashorn");
./spec/nashorn/AsciidoctorConvertWithNashorn.java:    engine.eval(new FileReader("./spec/nashorn/asciidoctor-convert.js"));
./spec/nashorn/BasicJavascriptWithNashorn.java:public class BasicJavascriptWithNashorn {
./spec/nashorn/BasicJavascriptWithNashorn.java:    ScriptEngine engine = engineManager.getEngineByName("nashorn");
./spec/nashorn/BasicJavascriptWithNashorn.java:    engine.eval(new FileReader("./spec/nashorn/basic.js"));

Die erste Hälfte des Befehls sollte jetzt verständlich sein. Aber was ist mit dem „^[\^:]*\\.java“-Teil?

Es sei denn, Sie geben das -F an Option grep geht davon aus, dass das Suchmuster ein regulärer Ausdruck ist. Das bedeutet, dass Sie zusätzlich zu einfachen Zeichen, die wörtlich übereinstimmen, Zugriff auf eine Reihe von Metazeichen haben, um komplexere Muster zu beschreiben. Das Muster, das ich oben verwendet habe, passt nur zu:

  • ^ Zeilenanfang
  • [^:]* gefolgt von einer Folge beliebiger Zeichen außer einem Doppelpunkt
  • \. gefolgt von einem Punkt (der Punkt hat in regex eine besondere Bedeutung , also musste ich es mit einem umgekehrten Schrägstrich schützen, um auszudrücken, dass ich eine wörtliche Übereinstimmung haben möchte)
  • java gefolgt von den vier Buchstaben „java.“

In der Praxis seit grep wird einen Doppelpunkt verwenden, um den Dateinamen vom Kontext zu trennen, ich behalte nur Zeilen mit .java im Abschnitt Dateiname. Erwähnenswert, dass es würde passen auch .javascript Dateinamen. Dies ist etwas, das ich versuchen lasse, es selbst zu lösen, wenn Sie möchten.

6. Filtern von Dateien nach ihrem Namen mit grep

Reguläre Ausdrücke sind extrem leistungsfähig. In diesem speziellen Fall scheint es jedoch übertrieben zu sein. Ganz zu schweigen von der obigen Lösung verbringen wir Zeit damit, alle Dateien auf der Suche nach dem „Nashorn“-Muster zu untersuchen – die meisten Ergebnisse werden vom zweiten Schritt der Pipeline verworfen.

Wenn Sie die GNU-Version von grep verwenden , was wahrscheinlich ist, wenn Sie Linux verwenden, Sie haben jedoch eine andere Lösung mit --include Möglichkeit. Dies weist grep an um nur nach Dateien zu suchen, deren Name mit dem gegebenen Glob-Muster übereinstimmt:

[email protected]:~$ grep -ir nashorn ./ --include='*.java'
./spec/nashorn/AsciidoctorConvertWithNashorn.java:public class AsciidoctorConvertWithNashorn {
./spec/nashorn/AsciidoctorConvertWithNashorn.java:    ScriptEngine engine = engineManager.getEngineByName("nashorn");
./spec/nashorn/AsciidoctorConvertWithNashorn.java:    engine.eval(new FileReader("./spec/nashorn/asciidoctor-convert.js"));
./spec/nashorn/BasicJavascriptWithNashorn.java:public class BasicJavascriptWithNashorn {
./spec/nashorn/BasicJavascriptWithNashorn.java:    ScriptEngine engine = engineManager.getEngineByName("nashorn");
./spec/nashorn/BasicJavascriptWithNashorn.java:    engine.eval(new FileReader("./spec/nashorn/basic.js"));

7. Wörter finden

Das Interessante am Asciidoctor.js-Projekt ist, dass es sich um ein mehrsprachiges Projekt handelt. Asciidoctor ist im Kern in Ruby geschrieben. Um in der JavaScript-Welt verwendet werden zu können, muss es mit Opal, einem Ruby-to-JavaScript-Source-to-Source-Compiler, „transpiliert“ werden. Eine weitere Technologie, die ich vorher nicht kannte.

Nachdem ich die Besonderheiten von Nashorn untersucht hatte, stellte ich mir die Aufgabe, die Opal-API besser zu verstehen. Als ersten Schritt bei dieser Suche habe ich alle Erwähnungen des Opal durchsucht globales Objekt in den JavaScript-Dateien des Projekts. Es könnte in Affektionen (Opal = ), Mitgliederzugang (Opal. ) oder vielleicht sogar in anderen Kontexten. Ein regulärer Ausdruck würde den Zweck erfüllen. Aber noch einmal, grep hat eine leichtere Lösung, um diesen häufigen Anwendungsfall zu lösen. Mit dem -w Option, werden nur Wörter gefunden , d. h. Muster, denen ein Nicht-Wort-Zeichen vorangeht und folgt. Ein Nicht-Wort-Zeichen ist entweder der Zeilenanfang, das Zeilenende oder ein beliebiges Zeichen, das weder ein Buchstabe noch eine Ziffer noch ein Unterstrich ist:

[email protected]:~$ grep -irw --include='*.js' Opal .
...

8. Einfärben der Ausgabe

Ich habe die Ausgabe des vorherigen Befehls nicht kopiert, da es viele Übereinstimmungen gibt. Wenn die Ausgabe so dicht ist, möchten Sie vielleicht ein wenig Farbe hinzufügen, um das Verständnis zu erleichtern. Wenn dies nicht bereits standardmäßig auf Ihrem System konfiguriert ist, können Sie diese Funktion mit dem GNU --color aktivieren Möglichkeit:

[email protected]:~$ grep -irw --color=auto --include='*.js' Opal .
...

Sie sollten das gleiche lange Ergebnis wie zuvor erhalten, aber diesmal sollte der Suchbegriff farbig erscheinen, falls dies nicht bereits der Fall war.

9. Zählen übereinstimmender Zeilen oder übereinstimmender Dateien

Ich habe zweimal erwähnt, dass die Ausgabe der vorherigen Befehle sehr lang war. Wie lange genau?

[email protected]:~$ grep -irw --include='*.js' Opal . | wc -l
86

Das heißt, wir haben eine Gesamtsumme 86 übereinstimmende Zeilen in all die untersuchten Akten. Wie viele verschiedene Dateien stimmen jedoch überein? Mit dem -l Option können Sie den grep einschränken gibt die passenden Dateien aus anstatt übereinstimmende Zeilen anzuzeigen . Diese einfache Änderung zeigt also an, wie viele Dateien übereinstimmen:

[email protected]:~$ grep -irwl --include='*.js' Opal . | wc -l
20

Falls Sie das an das -L erinnert Option, keine Überraschung:Wie es relativ üblich ist, werden Kleinbuchstaben/Großbuchstaben verwendet, um komplementäre Optionen zu unterscheiden. -l zeigt übereinstimmende Dateinamen an. -L zeigt nicht übereinstimmende Dateinamen an. Als weiteres Beispiel lasse ich Sie im Handbuch nach dem -h suchen /-H Optionen.

Lassen Sie uns diese Klammer schließen und zu unseren Ergebnissen zurückkehren:86 übereinstimmende Linien. 20 passende Dateien. Wie werden jedoch die passenden Zeilen verteilt in den passenden Dateien ? Wir können das mit dem -c wissen Option von grep die die Anzahl der übereinstimmenden Zeilen pro untersuchter Datei zählen (einschließlich Dateien mit null Übereinstimmungen):

[email protected]:~$ grep -irwc --include='*.js' Opal .
...

Diese Ausgabe erfordert häufig eine Nachbearbeitung, da sie ihre Ergebnisse in der Reihenfolge anzeigt, in der die Dateien untersucht wurden, und sie enthält auch Dateien ohne Übereinstimmung – etwas, das uns normalerweise nicht interessiert. Letzteres ist ganz einfach zu lösen:

[email protected]:~$ grep -irwc --include='*.js' Opal . | grep -v ':0$'

Was das Sortieren betrifft, können Sie den sort-Befehl am Ende der Pipeline hinzufügen:

[email protected]:~$ grep -irwc --include='*.js' Opal . | grep -v ':0$' | sort -t: -k2n

Ich lasse Sie die sort überprüfen Befehlshandbuch für die genaue Bedeutung der von mir verwendeten Optionen. Vergessen Sie nicht, Ihre Ergebnisse im Kommentarbereich unten zu teilen!

10. Den Unterschied zwischen zwei übereinstimmenden Sätzen finden

Wenn Sie sich erinnern, habe ich vor ein paar Befehlen nach dem Wort gesucht "Opal." Wenn ich jedoch im selben Dateisatz nach allen Vorkommen der Zeichenfolge suche „Opal“, erhalte ich etwa zwanzig weitere Antworten:

[email protected]:~$ grep -irw --include='*.js' Opal . | wc -l
86
[email protected]:~$ grep -ir --include='*.js' Opal . | wc -l
105

Es wäre interessant, den Unterschied zwischen diesen beiden Sätzen zu finden. Also, was sind die Zeilen, die die vier Buchstaben „opal“ in einer Reihe enthalten, aber wo diese vier Buchstaben kein ganzes Wort bilden?

So einfach ist diese Frage nicht zu beantworten. Weil das dasselbe Zeile kann beides enthalten das Wort Opal sowie ein größeres Wort, das diese vier Buchstaben enthält. Aber als erste Annäherung können Sie diese Pipeline verwenden:

[email protected]:~$ grep -ir --include='*.js' Opal . | grep -ivw Opal
./npm/examples.js:  const opalBuilder = OpalBuilder.create();
./npm/examples.js:  opalBuilder.appendPaths('build/asciidoctor/lib');
./npm/examples.js:  opalBuilder.appendPaths('lib');
...

Anscheinend wäre mein nächster Stopp, den opalBuilder zu untersuchen Objekt, aber das ist für einen anderen Tag.

Das letzte Wort

Natürlich werden Sie eine Projektorganisation, geschweige denn die Codearchitektur, nicht verstehen, indem Sie nur ein paar grep ausgeben Befehle!

Ich finde diesen Befehl jedoch unvermeidlich, um Benchmarks und Ausgangspunkte beim Erkunden einer neuen Codebasis zu identifizieren.

Ich hoffe also, dieser Artikel hat Ihnen geholfen, die Leistungsfähigkeit von grep zu verstehen Befehl und dass Sie ihn Ihrer Werkzeugkiste hinzufügen. Zweifellos werden Sie es nicht bereuen!


Linux
  1. 8 praktische Beispiele für den Linux-Xargs-Befehl für Anfänger

  2. 10 praktische Beispiele für die Verwendung des scp-Befehls

  3. cp-Befehl unter Linux:7 praktische Beispiele

  4. Linux-Shutdown-Befehl:5 praktische Beispiele

  5. nslookup-Befehl:7 praktische Beispiele

12 praktische Beispiele für In Command unter Linux

Die 40 Go-Befehlsbeispiele für angehende Golang-Entwickler

15 Praktische Beispiele für den Rsync-Befehl unter Linux

5 praktische Beispiele für Tail-Befehle unter Linux

15 Praktische Grep-Befehlsbeispiele in Linux / UNIX

UNIX / Linux:7 praktische Beispiele für PS-Befehle zur Prozessüberwachung