Wie füge ich eine neue Zeile vor einem Muster innerhalb einer Zeile ein?
Dadurch wird beispielsweise eine neue Zeile hinter dem Regex-Muster eingefügt .
sed 's/regex/&\n/g'
Wie kann ich das gleiche tun, aber vor dem Muster?
In dieser Beispiel-Eingabedatei ist das Muster, mit dem die Übereinstimmung übereinstimmt, die Telefonnummer.
some text (012)345-6789
Soll werden
some text
(012)345-6789
sed '/regex/G'
Antworten:
Dies funktioniert unter
bash
undzsh
unter Linux und OS X getestet:Im Allgemeinen wird,
$
gefolgt von einem Zeichenfolgenliteral in einfachen Anführungszeichen,bash
eine Backslash-Ersetzung im C-Stil durchgeführt, z. B.$'\t'
wird sie in eine Literal-Registerkarte übersetzt. Plus, sed will Ihr Newline wörtlichen mit einem Backslash geschützt werden, damit die\
vor$
. Und schließlich sollte das Dollarzeichen selbst nicht in Anführungszeichen gesetzt werden, damit es von der Shell interpretiert wird. Deshalb schließen wir das Anführungszeichen vor dem$
und öffnen es dann erneut.Bearbeiten : Wie in den Kommentaren von @ mklement0 vorgeschlagen, funktioniert dies auch:
Was hier passiert, ist: Der gesamte Befehl sed ist jetzt eine Zeichenfolge im C-Stil. Dies bedeutet, dass der Backslash, den sed vor dem neuen Zeilenliteral platzieren muss, jetzt mit einem anderen Backslash maskiert werden soll. Obwohl besser lesbar, können Sie in diesem Fall keine Shell-String-Ersetzungen vornehmen (ohne es erneut hässlich zu machen.)
quelle
sed '\(first match\)\(second match\)/\1\'$'\n''\2/g'
. Beachten Sie die beiden einfachen Anführungszeichen nach dem \ n. Der erste schließt den$
Abschnitt " " ab, damit der Rest der Zeile davon nicht betroffen ist. Ohne diese Anführungszeichen wurde die \ 2 ignoriert.sed $'s/regexp/\\\n/g'
Dies verbessert die Lesbarkeit. Die einzige Einschränkung besteht darin, dass Sie dann alle Literalzeichen verdoppeln müssen\
.Einige der anderen Antworten funktionierten für meine Version von sed nicht. Position wechseln
&
und\n
hat funktioniert.Bearbeiten: Dies scheint unter OS X nicht zu funktionieren, es sei denn, Sie installieren
gnu-sed
.quelle
brew install gnu-sed
gefolgt vongsed 's/regexp/\n&/g'
echo 'alias sed=gsed' >> ~/.bashrc
In sed können Sie dem Ausgabestream nicht einfach Zeilenumbrüche hinzufügen. Sie müssen eine Fortsetzungszeile verwenden, was umständlich ist, aber funktioniert:
Beispiel:
Siehe hier für Details. Wenn Sie etwas weniger umständliches wollen, können Sie versuchen, es
perl -pe
mit Matchgruppen anstelle von sed zu verwenden:$1
bezieht sich auf die erste übereinstimmende Gruppe im regulären Ausdruck, wobei Gruppen in Klammern stehen.quelle
perl -pi -e 's/(.*)/\n$1/' foo
s
Funktionsaufrufs (im Gegensatz zur GNU Sed-Implementierung, die dies tut). . Die obige Antwort funktioniert mit beiden Implementierungen. Eine Übersicht aller Unterschiede finden Sie hier .Auf meinem Mac wird im Folgenden ein einzelnes 'n' anstelle einer neuen Zeile eingefügt:
Dies wird durch Zeilenumbruch ersetzt:
quelle
sed -i '' -e ...
und hatte Probleme damit, dass ein^M
Caret M (Strg + M) in die Datei geschrieben wurde. Am Ende habe ich Perl mit den gleichen Parametern verwendet.\n
).echo...
und newline gut funktionierte), dass ich dies nur in vim tat.sed "s/regexp/`echo`/g"
- Dies erzeugt einen einzelnen LF anstelle von LF-CR`echo`
führt zu einer leeren Zeichenfolge , da Befehlsersetzungen immer alle nachfolgenden Zeilenumbrüche kürzen. Es gibt keine Möglichkeit, eine Befehlsersetzung zu verwenden, um eine einzelne neue Zeile direkt einzufügen (und das Einfügen\n\r
- dh eines zusätzlichen CR - ist eine schreckliche Idee).quelle
$'\n'
verlässt sich auf die Shell, um die neue Zeile zu generieren. Solche Lösungen sind möglicherweise nicht tragbar. Dieser ist. Natürlich ist es auch ein Duplikat des zweiten Beispiels in Tgamblins Antwort von 2009.In diesem Fall benutze ich nicht sed. Ich benutze tr.
Dies nimmt das Komma und ersetzt es durch den Wagenrücklauf.
quelle
cat Somefile | tr ',' '\n'
YMMVSie können Perl-Einzeiler verwenden, ähnlich wie Sie es mit sed tun, mit dem Vorteil der vollständigen Unterstützung von Perl-regulären Ausdrücken (die viel leistungsfähiger ist als das, was Sie mit sed erhalten). Es gibt auch sehr geringe Unterschiede zwischen * nix-Plattformen - Perl ist im Allgemeinen Perl. Sie können also aufhören, sich Gedanken darüber zu machen, wie Sie die sed-Version Ihres bestimmten Systems dazu bringen können, das zu tun, was Sie wollen.
In diesem Fall können Sie tun
-pe
Versetzt Perl in eine "Execute and Print" -Schleife, ähnlich wie bei der normalen Betriebsart von sed.'
zitiert alles andere, damit die Shell nicht stört()
Um den regulären Ausdruck herum befindet sich ein Gruppierungsoperator.$1
Auf der rechten Seite der Substitution wird gedruckt, was in diesen Parens übereinstimmte.Schließlich
\n
ist eine neue Zeile.Unabhängig davon, ob Sie Klammern als Gruppierungsoperator verwenden, müssen Sie alle Klammern, mit denen Sie übereinstimmen möchten, maskieren. Ein Regex, der dem oben aufgeführten Muster entspricht, wäre also so etwas wie
\(
oder\)
entspricht einem wörtlichen Paren und\d
einer Ziffer.Besser:
Ich kann mir vorstellen, dass Sie herausfinden können, was die Zahlen in geschweiften Klammern bewirken.
Darüber hinaus können Sie andere Trennzeichen als / für Ihre Regex verwenden. Wenn Sie also übereinstimmen müssen, müssen Sie nicht entkommen. Beides entspricht dem regulären Ausdruck zu Beginn meiner Antwort. Theoretisch können Sie die Standards durch ein beliebiges Zeichen ersetzen .
Ein paar letzte Gedanken.
Verwenden
-ne
anstelle von-pe
verhält sich ähnlich, druckt aber am Ende nicht automatisch. Dies kann nützlich sein, wenn Sie selbst drucken möchten. Beispiel: Hier ist ein Grep-Alike (m/foobar/
ist ein Regex-Match):Wenn Sie Probleme beim Umgang mit Zeilenumbrüchen haben und möchten, dass diese auf magische Weise für Sie erledigt werden, fügen Sie hinzu
-l
. Nicht nützlich für das OP, das mit Zeilenumbrüchen arbeitete.Bonus-Tipp - Wenn Sie das PCRE-Paket installiert haben, wird es mitgeliefert
pcregrep
, das vollständige Perl-kompatible Regexes verwendet.quelle
Hmm, gerade entkommene Zeilenumbrüche scheinen in neueren Versionen von
sed
(ich habe GNU sed 4.2.1) zu funktionieren ,quelle
hat mit
()
Unterstützung gut an El Captitan funktioniertquelle
Um eine neue Zeile für den Ausgabestream unter Linux einzufügen, habe ich Folgendes verwendet:
Wo
file1
war:Vor dem Sed-In-Place-Austausch und:
Nach dem Sed-In-Place-Austausch. Bitte beachten Sie die Verwendung von
\\\n
. Wenn die Muster ein"
Inneres haben, entkommen Sie mit\"
.quelle
sed
Einfügungen\n
anstelle von LF, da\\n
der Parameter von der Shell abgerufen wird. --- Dieser Code funktioniert :sed -i "s/def/abc\ndef/" file1
. ---GNU sed version 4.2.1
,GNU bash, version 4.1.2(1) / 4.2.25(1)
(CentOS Release 6.4 / Ubuntu 12.04.3).In sed können Sie Gruppen in Ihrem Muster mit "\ 1", "\ 2" usw. referenzieren. Wenn das gesuchte Muster also "MUSTER" ist und Sie "VOR" davor einfügen möchten , können Sie verwenden, ohne zu entkommen
dh
quelle
Sie können dies auch mit awk tun, indem Sie
-v
das Muster bereitstellen:Dies prüft, ob eine Zeile ein bestimmtes Muster enthält. In diesem Fall wird eine neue Zeile an den Anfang angehängt.
Sehen Sie sich ein einfaches Beispiel an:
Beachten Sie, dass dies Auswirkungen auf alle Muster in einer Zeile hat:
quelle
1
wird in Awk als Abkürzung für verwendet{print $0}
. Der Grund dafür ist, dass jede Bedingung, die als True ausgewertet wird, die Standardaktion von Awk auslöst, die darin besteht, den aktuellen Datensatz zu drucken.Dies funktioniert in MAC für mich
Dono ob es perfekt ist ...
quelle
Nachdem ich alle Antworten auf diese Frage gelesen hatte, brauchte ich noch viele Versuche, um die richtige Syntax für das folgende Beispielskript zu erhalten:
Das Skript fügt
\n
mit einem einzigensed
Befehl eine neue Zeile gefolgt von einer weiteren Textzeile an das Ende einer Datei an .quelle
\ 0 ist die Null, also wird Ihr Ausdruck durch Null (nichts) ersetzt und dann ...
\ n ist die neue Zeile
Bei einigen Unix-Versionen funktioniert das nicht, aber ich denke, es ist die Lösung für Ihr Problem.
quelle
In vi auf Red Hat konnte ich Wagenrückläufe nur mit dem Zeichen \ r einfügen. Ich glaube, dass dies intern 'ex' anstelle von 'sed' ausführt, aber es ist ähnlich, und vi kann eine andere Möglichkeit sein, Massenbearbeitungen wie Code-Patches durchzuführen. Beispielsweise. Ich umgebe einen Suchbegriff mit einer if-Anweisung, die darauf besteht, dass der Wagen nach den Klammern zurückkehrt:
Beachten Sie, dass ich auch einige Registerkarten einfügen musste, um die Ausrichtung zu verbessern.
quelle