Mit Standard sehen sedSie niemals eine neue Zeile im Text, der aus einer Datei gelesen wird. Dies liegt daran, dass sedzeilenweise gelesen wird und daher am Ende des Textes der aktuellen Zeile im Musterbereich keine neue Zeile steht sed. Mit anderen Worten, sedliest durch Zeilenumbrüche getrennte Daten, und die Trennzeichen sind nicht Teil dessen, was ein sedSkript sieht.
Reguläre Ausdrücke können am Ende der Zeile mit (oder am Anfang mit ) verankert$ werden ^. Wenn Sie einen Ausdruck am Anfang / Ende einer Zeile verankern, wird er genau dort und nicht nur irgendwo in der Zeile angezeigt.
Wenn Sie etwas, das mit dem Muster [A-Za-z]*am Ende der Zeile übereinstimmt, durch etwas ersetzen möchten , verankern Sie das Muster wie folgt:
[A-Za-z]*$
... erzwingt, dass es am Ende der Zeile und nirgendwo anders übereinstimmt.
Da jedoch [A-Za-z]*$auch nichts übereinstimmt (z. B. die leere Zeichenfolge am Ende jeder Zeile), müssen Sie den Abgleich von etwas erzwingen , z. B. durch Angabe
[A-Za-z][A-Za-z]*$
So wird Ihre sed Kommandozeile also sein
$ sed 's/[A-Za-z][A-Za-z]*$/replace/' file.txt
Ich habe den -ESchalter hier nicht verwendet , weil er nicht benötigt wird. Damit hättest du schreiben können
Obwohl ich wusste, wie man das macht, erhalten Sie eine +1, nur wenn Sie den Fachbegriff dafür verwenden. :) Das nennt man also Verankerung - schön zu wissen. Bis jetzt musste ich es immer umschreiben ... Ein weiterer Hinweis+ zum Thema : Sie können es auch ohne erweiterten regulären Ausdruck verwenden. Denken Sie daran, es so zu schreiben \+. Funktioniert also sed -e 's/[A-Za-z]\+$/replace/' file.txtauch ohne sedinstallierte GNU einwandfrei . Und nicht zu vergessen: Nicht verwenden -E, da GNU seddies nicht unterstützt .
Syntaxfehler
1
@syntaxerror - Ich denke, Sie können den letzten Satz entfernen oder zumindest aufheben, da dies gnu seddefinitiv unterstützt wird-E .
don_crissti
@don_crissti Nun, ich dachte, Sie sind lange genug in diesem Netzwerk, um zu wissen, dass es keine Möglichkeit gibt, Teile eines Kommentars aufzuheben (es sei denn, Sie schreiben ihn vollständig neu). Lassen Sie mich also Folgendes korrigieren: GNU unterstützt sedmöglicherweise "stillschweigend" -E, dies ist jedoch weder in der Manpage (noch im Texinfo-Handbuch (beide aktiviert)) dokumentiert . Daher habe ich angenommen, dass es nicht unterstützt wird (was schließlich eine falsche Annahme war). Wie auch immer, Sie haben Recht, denn zumindest wird sich GNU sednicht beschweren, wenn Sie diese Option verwenden.
Syntaxfehler
@don_crissti Schön, dass du es getan hast! So zumindest hat sich bestätigt, dass sedwird eine bestimmte Option nehmen , die noch nicht richtig dokumentiert worden. Das ist immer praktisch; Wenn niemand über den Mangel an Dokumentation informiert ist, wird niemand dies jemals beheben.
Syntaxfehler
@syntaxerror, siehe unix.stackexchange.com/a/310454/135943 . Wenn Sie mit alten Systemen wie RHEL 5 arbeiten müssen, verwenden Sie natürlich eine GNU sed-Version, die nicht unterstützt wird -E.
Wildcard
3
sed "s/[a-zA-Z]*$/replace/" input.txt > result.txt
Oder der lange komplexe unnötige Weg:
Ich habe herausgefunden, dass dies mit Hilfe von tr unter Verwendung von sed möglich ist. Sie können ein anderes Zeichen zuweisen, um das Ende der Zeile darzustellen. Ein anderes temporäres Zeichen muss verwendet werden, in diesem Fall "` ". Verwenden wir "~", um das Ende der Zeile darzustellen:
Ich bin mir nicht sicher, ob ich das verstehe ... Warum verankerst du dich nicht einfach am Ende der Linie $? zBs/[a-zA-Z]*$/replace/
don_crissti
1
2 Punkte: 1) Du solltest besser nutzen \+statt , *da diese ermöglichen Null Buchstaben am Ende der Zeichenfolge; 2) Sie können eine Zeichenklasse verwenden [[:alpha:]]. Also:sed 's/[[:alpha:]]\+$/replace/' file
Glenn Jackman
@glennjackman Wofür ist der Backslash vor dem Plus? Würde das nicht zum Zusatzzeichen passen?
Aus dem (defekten) Code-Snippet, das Sie gepostet haben, möchten Sie anscheinend auch die neue Zeile ersetzen. In diesem Fall kann Ihnen die Regex-Verankerung an sich nicht helfen. Folgendes ist eine Lösung:
sed '/[[:alpha:]]\+$/{N;s/[[:alpha:]]\+\n/replace/}' your_file
Heruntergebrochen:
/[a-zA-Z]\+$/{} bedeutet, dass alles, was in den Locken enthalten ist, auf Linien angewendet wird, die mit dem regulären Ausdruck übereinstimmen.
Innerhalb der Locken Nbedeutet "die nächste Zeile an den aktiven Puffer anhängen" (was sedals "Musterraum" bezeichnet wird)
Schließlich ist die s///Aussage Ihre erforderliche Ersetzung. Es funktioniert jetzt, weil der Musterraum zwei aufeinanderfolgende Zeilen enthält und die neue Zeile daher ein Teil davon ist.
+
zum Thema : Sie können es auch ohne erweiterten regulären Ausdruck verwenden. Denken Sie daran, es so zu schreiben\+
. Funktioniert alsosed -e 's/[A-Za-z]\+$/replace/' file.txt
auch ohnesed
installierte GNU einwandfrei . Und nicht zu vergessen: Nicht verwenden-E
, da GNUsed
dies nicht unterstützt .gnu sed
definitiv unterstützt wird-E
.sed
möglicherweise "stillschweigend"-E
, dies ist jedoch weder in der Manpage (noch im Texinfo-Handbuch (beide aktiviert)) dokumentiert . Daher habe ich angenommen, dass es nicht unterstützt wird (was schließlich eine falsche Annahme war). Wie auch immer, Sie haben Recht, denn zumindest wird sich GNUsed
nicht beschweren, wenn Sie diese Option verwenden.sed
wird eine bestimmte Option nehmen , die noch nicht richtig dokumentiert worden. Das ist immer praktisch; Wenn niemand über den Mangel an Dokumentation informiert ist, wird niemand dies jemals beheben.-E
.Oder der lange komplexe unnötige Weg:
quelle
$
? zBs/[a-zA-Z]*$/replace/
\+
statt ,*
da diese ermöglichen Null Buchstaben am Ende der Zeichenfolge; 2) Sie können eine Zeichenklasse verwenden[[:alpha:]]
. Also:sed 's/[[:alpha:]]\+$/replace/' file
-r
Option verwendet diese Syntax für reguläre Ausdrücke .Aus dem (defekten) Code-Snippet, das Sie gepostet haben, möchten Sie anscheinend auch die neue Zeile ersetzen. In diesem Fall kann Ihnen die Regex-Verankerung an sich nicht helfen. Folgendes ist eine Lösung:
Heruntergebrochen:
/[a-zA-Z]\+$/{}
bedeutet, dass alles, was in den Locken enthalten ist, auf Linien angewendet wird, die mit dem regulären Ausdruck übereinstimmen.N
bedeutet "die nächste Zeile an den aktiven Puffer anhängen" (wassed
als "Musterraum" bezeichnet wird)s///
Aussage Ihre erforderliche Ersetzung. Es funktioniert jetzt, weil der Musterraum zwei aufeinanderfolgende Zeilen enthält und die neue Zeile daher ein Teil davon ist.quelle
Um das Zeilenende zu finden, verwenden Sie einfach das $ -Zeichen :
Ohne Zeilenende Anker:
Ohne Zeilenende Anker:
quelle