Ich versuche, eine Zeichenfolge auszugeben, die alles zwischen zwei Wörtern einer Zeichenfolge enthält:
Eingang:
"Here is a String"
Ausgabe:
"is a"
Verwenden von:
sed -n '/Here/,/String/p'
enthält die Endpunkte, aber ich möchte sie nicht einschließen.
Here is a Here String
? OderI Hereby Dub Thee Sir Stringy
?Antworten:
quelle
echo "Here is a one is a String" | sed -e 's/one is\(.*\)String/\1/'
. Wenn Sie nur den Teil zwischen "one is" und "String" haben möchten, müssen Sie den regulären Ausdruck so einstellen, dass er mit der gesamten Zeile übereinstimmt :sed -e 's/.*one is\(.*\)String.*/\1/'
.s/pattern/replacement/
Sagen Sie in sed "Ersetzen Sie" Muster "durch" Muster "in jeder Zeile". Es wird nur alles geändert, was mit "Muster" übereinstimmt. Wenn Sie also möchten, dass es die gesamte Zeile ersetzt, müssen Sie "Muster" an die gesamte Zeile anpassen.Here is a String Here is a String
GNU grep kann auch positive und negative Vorausschau und Rückschau unterstützen: Für Ihren Fall wäre der Befehl:
Wenn es mehrere Vorkommen von
Here
und gibtstring
, können Sie auswählen, ob Sie zwischen dem erstenHere
und dem letztenstring
übereinstimmen möchten oder ob Sie sie einzeln abgleichen möchten . In Bezug auf Regex wird es als gieriges Match (erster Fall) oder nicht gieriges Match (zweiter Fall) bezeichnet.quelle
-P
Option von GNU grep in dergrep
in * BSD enthaltenen oder mit SVR4 (Solaris usw.) gelieferten Option nicht vorhanden ist . In FreeBSD können Sie dendevel/pcre
Port installierenpcregrep
, der PCRE (und Look-Ahead / Behind) unterstützt. Ältere Versionen von OSX verwendeten GNU grep, wurden jedoch in OSX Mavericks-P
von der FreeBSD-Version abgeleitet, die diese Option nicht enthält.Here is a string a string
sind beide" is a "
und" is a string a "
gültige Antworten (ignorieren Sie die Anführungszeichen) gemäß den Fragenanforderungen. Es hängt von Ihnen ab, welche davon Sie möchten, und die Antwort kann entsprechend unterschiedlich sein. Wie auch immer, für Ihre Anforderung wird dies funktionieren:echo "Here is a string a string" | grep -o -P '(?<=Here).*?(?=string)'
echo $'Here is \na string' | grep -zoP '(?<=Here)(?s).*(?=string)'
Die akzeptierte Antwort entfernt keinen Text, der vorher
Here
oder nachher sein könnteString
. Dieser Wille:Der Hauptunterschied ist die Zugabe von
.*
unmittelbar davorHere
und danachString
.quelle
*
Quantifizierer zwischenHere
undString
nicht gierig (oder faul) machen. Der von sed verwendete Regex-Typ unterstützt jedoch keine Lazy-Quantifizierer (?
unmittelbar danach.*
) gemäß dieser Stackoverflow-Frage. Um einen faulen Quantifizierer zu implementieren, würden Sie normalerweise nur mit allem übereinstimmen, außer mit dem Token, mit dem Sie nicht übereinstimmen wollten. In diesem Fall gibt es jedoch nicht nur ein einzelnes Token, sondern eine ganze ZeichenfolgeString
..
stimmt nicht mit Zeilenumbrüchen überein. Wenn Sie Zeilenumbrüche abgleichen möchten, können Sie diese durch.
etwas ersetzen[\s\s]
.Sie können Strings nur in Bash entfernen:
Und wenn Sie ein GNU-Grep haben, das PCRE enthält , können Sie eine Zusicherung mit einer Breite von Null verwenden:
quelle
Durch GNU awk,
grep mit
-P
( perl-regexp ) -Parameterunterstützung\K
, die beim Verwerfen der zuvor übereinstimmenden Zeichen hilft. In unserem Fall war die zuvor übereinstimmende ZeichenfolgeHere
so, dass sie aus der endgültigen Ausgabe verworfen wurde.Wenn Sie möchten, dass die Ausgabe erfolgt, können
is a
Sie Folgendes versuchen:quelle
echo "Here is a string dfdsf Here is a string" | awk -v FS="(Here|string)" '{print $2}'
, es kehrt nur zurückis a
anstatt sollteis a is a
@Avinash Raj seinWenn Sie eine lange Datei mit vielen mehrzeiligen Vorkommen haben, ist es hilfreich, zuerst Zahlenzeilen zu drucken:
quelle
-n
Option incat
weggelassen werden.cat
kann ganz weggelassen werden;sed
weiß, wie man eine Datei oder eine Standardeingabe liest.Dies könnte für Sie funktionieren (GNU sed):
Dadurch wird jede Darstellung von Text zwischen zwei Markierungen (in diesem Fall
Here
undString
) in einer neuen Zeile dargestellt und die neuen Zeilen im Text bleiben erhalten.quelle
Alle oben genannten Lösungen weisen Mängel auf, bei denen die letzte Suchzeichenfolge an anderer Stelle in der Zeichenfolge wiederholt wird. Ich fand es am besten, eine Bash-Funktion zu schreiben.
quelle
Sie können zwei s-Befehle verwenden
Funktioniert auch
quelle
Verstehen
sed
Befehl , müssen wir ihn Schritt für Schritt erstellen.Hier ist Ihr Originaltext
Versuchen wir, einen
Here
String mit ders
Option ubstition in zu entfernensed
An diesem Punkt, ich glaube , Sie wäre in der Lage sein , zu entfernen
String
undDies ist jedoch nicht die gewünschte Ausgabe.
Verwenden Sie die
-e
Option, um zwei sed-Befehle zu kombinierenHoffe das hilft
quelle
Sie können verwenden
\1
(siehe http://www.grymoire.com/Unix/Sed.html#uh-4 ):Der Inhalt in den Klammern wird als gespeichert
\1
.quelle
Problem. Meine gespeicherten Claws Mail-Nachrichten werden wie folgt verpackt, und ich versuche, die Betreffzeilen zu extrahieren:
Gemäß A2 in diesem Thread: Wie kann man mit sed / grep Text zwischen zwei Wörtern extrahieren? Der erste Ausdruck unten "funktioniert", solange der übereinstimmende Text keine neue Zeile enthält:
Trotz zahlreicher Varianten (
.+?; /s; ...
) konnte ich diese jedoch nicht zum Laufen bringen:Lösung 1.
Per Text zwischen zwei Zeichenfolgen in verschiedenen Zeilen extrahieren
was gibt
Lösung 2. *
Per Wie kann ich eine neue Zeile (\ n) mit sed ersetzen?
ersetzt Zeilenumbrüche durch ein Leerzeichen.
Verketten Sie das mit A2 in Wie verwende ich sed / grep, um Text zwischen zwei Wörtern zu extrahieren? , wir bekommen:
was gibt
Diese Variante entfernt doppelte Leerzeichen:
geben
quelle