Ich möchte nach Text suchen, der in einer Datei über mehrere Zeilen verteilt sein kann. Ein Grep, der Zeilenumbrüche ignoriert und die übereinstimmende Zeilenbreite zurückgibt.
zB würde ich suchen is an example file
und erwarten, dass es in der folgenden Datei gefunden wird:
Dies ist
eine
Beispieldatei.
Um nicht von führenden oder nachfolgenden Leerzeichen abhängig zu sein, ist es möglicherweise am besten, alle Formen von Leerzeichen vollständig zu ignorieren (im Idealfall wird jede Folge von Leerzeichen als ein einzelnes Leerzeichen behandelt).
Eine nicht ideale Lösung besteht darin tr '\n' ' ' | grep
, zwischen Übereinstimmungen und Nichtübereinstimmungen zu unterscheiden, die Übereinstimmung jedoch nicht anzuzeigen und auch nicht gut mit großen Dateien umzugehen.
quelle
isearch-forward
)/This\_sis
. Für weitere Details ::help \_s
.Antworten:
Die GNU
grep
kann es tunUm einige Punkte zu erfüllen, die in Kommentaren auftreten, wurden einige Änderungen am Skript vorgenommen:
In Bezug auf große Dateien habe ich keine Vorstellung von Speicherbeschränkungen, aber im Falle eines Problems können Sie diese frei verwenden
sed
das hält nicht mehr als 4 Zeilen (weil 4 Wörter im Muster) im Speicher (
\(\n.*\)\{3\}
).quelle
-z
Optiongrep
an, Zeilenumbrüche als normale Textzeichen zu behandeln und nach Null-Bytes zu suchen, um Datensätze zu trennen. In einer Textdatei ohne Nullbytes (dh im typischen Fall)grep -z
wird die gesamte Datei als eine Zeile behandelt. (1) Dies wirft die Frage auf, wie gut es mit großen Dateien umgehen kann, und (2) wenn es eine Übereinstimmung findet, schreibt es die gesamte Datei aus und gibt keinen Hinweis auf den Ort der Übereinstimmung. Außerdem (3) sagte das OP: „Idealerweise wird jede Folge von Leerzeichen als ein einzelnes Leerzeichen behandelt. Sie sollten sie also verwenden\s+
und hinzufügen-E
.-o
; Das vergesse ich immer wieder. Clevere Art, es zu benutzen. (1) Ihre neuegrep
Antwort beginnt^[\n]*
; das ist ein Tippfehler für[^\n]*
. (2) Ich sagte\s+
absichtlich.be\s*little
wird übereinstimmenbelittle
undcare\s*less
wird übereinstimmencareless
. Aber ich denke, das ist ein kleines Problem. Und wenn Sie nicht verwenden möchten-E
, können Sie "die Version des armen Mannes" von verwenden\s+
, nämlich\s\s*
. (3) Nettersed
Befehl. Es kann fehlschlagen, wenn Leerzeilen vorhanden sind (die Phrase mit vier Wörtern kann sich also über mehr als vier Zeilen erstrecken). Ich konnte das durch Hinzufügen behebens/\n\s*\n/\n/
.-E
Sie Stahl+
in\s\+
Form verwenden können. Leere Linien innerhalb des Musters scheinen erfunden zu sein.grep
auf Phrasen hoffen können.Versuche dies:
quelle
\s
5 Mal eingeben, wenn ich nach "Dies ist ein sehr langes Muster" suche?\s
stimmt mit Leerzeichen überein, und Newline ist ein "Leerzeichen".This\nis a very\nlong pattern
und ich nicht weiß, wo die Zeilenumbrüche auftreten könnten. Ich müsste suchenThis\sis\sa\svery\slong\spattern
, oder? (was langweilig wird, wenn die Länge des Musters zunimmt oder von einer anderen Stelle eingefügt wird)pcregrep -M "$( echo 'This is a very long pattern' | sed 's/ /\\s+/g' )" file
.