Ich benutze oft grep, um Dateien mit einem bestimmten Eintrag wie dem folgenden zu finden:
grep -R 'MyClassName'
Das Gute ist, dass es die Dateien und ihren Inhalt zurückgibt und die gefundene Zeichenfolge rot markiert. Das Schlimme ist, dass ich auch riesige Dateien habe, in denen der gesamte Text in einer großen Zeile geschrieben ist. Jetzt gibt grep zu viel aus, wenn Text in diesen großen Dateien gefunden wird. Gibt es eine Möglichkeit, die Ausgabe auf beispielsweise 5 Wörter links und rechts zu beschränken? Oder beschränken Sie die Ausgabe auf 30 Buchstaben links und rechts?
command-line
text-processing
grep
Sokrates
quelle
quelle
cut
cut
, da es nur nach Trennzeichen oder nach Anzahl der Zeichen aufgeteilt wird. Wenn ich eine LinieMyClassName
damit finde , kann sie sich jedoch irgendwo in der Linie befinden und nicht immer an derselben Position. Darüber hinaus kann es vorne und hinten zu einer Variation von Zeichen kommen, wodurch die Möglichkeit einer Aufteilung nach Trennzeichen aufgehoben wird.MyClassName
gefunden wurde, möchte ich als Ergebnis den Dateinamen und die x Zeichen links und rechts erhalten. x ist eine beliebige Zahl, die ich angegeben habe, zum Beispiel 30. Der Rest des Dateiinhalts wird ignoriert. Dies dient dazu, einen Kontext zu den übereinstimmenden Dateien zu erhalten und die Überlastung zu begrenzen.cut
wenn drei Dateien mit der folgenden Eingabe vorhanden sind:oiadfaosuoianavMyClassNameionaernaldfajd
und/(/&%%§%/(§(/MyClassName&((/$/$/(§/$&
undpublic class MyClassName { public static void main(String[] args) { } }
?Antworten:
grep
selbst hat nur Optionen für den Kontext basierend auf Linien. Eine Alternative wird in diesem SU-Beitrag vorgeschlagen :Als weitere Alternative würde ich vorschlagen,
fold
den Text zu verwenden und ihn dann zu erfassen, zum Beispiel:Mit dieser
-s
Option werdenfold
Push-Wörter in die nächste Zeile verschoben, anstatt dazwischen zu brechen.Oder verwenden Sie eine andere Methode, um die Eingabe basierend auf der Struktur Ihrer Eingabe in Zeilen aufzuteilen. (Der SU-Beitrag befasste sich zum Beispiel mit JSON, also wäre es besser ,
jq
usw. zum hübschen Drucken zu verwenden undgrep
... oder einfachjq
nur das Filtern selbst durchzuführen ... als eine der beiden oben angegebenen Alternativen.)Diese GNU awk-Methode ist möglicherweise schneller:
-v RS=...
), und der Anzahl der Zeichen im Kontext (-v n=...
) zu teilen.FNR > 1
) ist einer, bei dem awk eine Übereinstimmung mit dem Muster gefunden hat.n
nachfolgende Zeichen aus der vorherigen Zeile (p
) undn
führende Zeichen aus der aktuellen Zeile (substr($0, 0, n)
) zusammen mit dem übereinstimmenden Text für die vorherige Zeile (dhprt
).p
undprt
nach dem Drucken, so dass der Wert, den wir setzen, von der nächsten Zeile verwendet wirdRT
ist ein GNUismus, deshalb ist dies GNU awk-spezifisch.Für die rekursive Suche vielleicht:
quelle
fold
Methode kann nur verwendet werden, wenn Sie sicher sind, dass die gesuchte Zeichenfolge nicht am Rand angezeigt wird, da sie sonst von ausgeblendet wirdgrep
.gawk
. Leider gibt der vorgeschlagene Befehl mitfind
zufälligen Dingen und ohne Dateinamen aus, wenn er auf meinem System ausgeführt wird. Außerdem bin ich nicht fließend genugawk
, um den Befehl richtig zu analysieren. Derzeitgrep
löst Regex in Kombination mit die Angelegenheit möglicherweise nicht schnell, aber zuverlässig. Nochmals vielen Dank.RT
Präfixe usw. verwendet werden sollten.Die Verwendung von Nur-Matching in Kombination mit einigen anderen Optionen (siehe unten) kann sehr nahe an dem liegen, was Sie suchen, ohne den in der anderen Antwort erwähnten Verarbeitungsaufwand für Regex
quelle
MyClassName
. Daher fehlt der Kontext.grep -RnHo "MyClassName"
undgrep -Rno "MyClassName"
haben die gleiche Ausgabe.-o
Flag könnte interessant sein, wenn der reguläre Ausdruck einen variablen Teil hat. Für eine feste Zeichenfolge ist es sinnlos, sie jedes Mal zu drucken. OP ist höchstwahrscheinlich am nahen Kontext interessiert.-B 1
) oder nach (-A 1
) hinzufügen . Entschuldigung, dass ich nicht weiterhelfen konnte.