it-swarm.com.de

Zeile nach dem ersten Spiel mit sed einfügen

Aus irgendeinem Grund kann ich scheinbar keine einfache Antwort darauf finden, und ich bin momentan in einer Zeitnot. Wie gehe ich vor, um eine Auswahlzeile mit dem Befehl sed nach der ersten Zeile einzufügen, die mit einer bestimmten Zeichenfolge übereinstimmt. Ich habe ...

CLIENTSCRIPT="foo"
CLIENTFILE="bar"

Und ich möchte nach der CLIENTSCRIPT=-Zeile eine Zeile einfügen, die ...

CLIENTSCRIPT="foo"
CLIENTSCRIPT2="hello"
CLIENTFILE="bar"
194
user2150250

Versuchen Sie dies mit GNU sed:

sed '/CLIENTSCRIPT="foo"/a CLIENTSCRIPT2="hello"' file

wenn Sie in-place ersetzen möchten, verwenden Sie

sed -i '/CLIENTSCRIPT="foo"/a CLIENTSCRIPT2="hello"' file

Ausgabe

CLIENTSCRIPT="foo"
CLIENTSCRIPT2="hello"
CLIENTFILE="bar"

Doc

  • siehe sed doc und suche \a (anhängen)
313
Gilles Quenot

Beachten Sie die Standardsyntax sed (wie in POSIX, die von allen entsprechenden sed-Implementierungen (GNU, OS/X, BSD, Solaris ...) unterstützt wird:

sed '/CLIENTSCRIPT=/a\
CLIENTSCRIPT2="hello"' file

Oder in einer Zeile:

sed -e '/CLIENTSCRIPT=/a\' -e 'CLIENTSCRIPT2="hello"' file

(-expressions (und der Inhalt von -files) werden mit neuen Zeilen verbunden, um das sed-Skript sed interpretiert zu werden.

Die -i-Option für die direkte Bearbeitung ist auch eine Erweiterung GNU. Einige andere Implementierungen (wie FreeBSDs) unterstützen -i '' dafür.

Alternativ können Sie für die Portabilität stattdessen Perl verwenden:

Perl -pi -e '$_ .= qq(CLIENTSCRIPT2="hello"\n) if /CLIENTSCRIPT=/' file

Oder Sie könnten ed oder ex verwenden:

printf '%s\n' /CLIENTSCRIPT=/a 'CLIENTSCRIPT2="hello"' . w q | ex -s file
42

Eine POSIX-kompatible Version, die den Befehl s verwendet:

sed '/CLIENTSCRIPT="foo"/s/.*/&\
CLIENTSCRIPT2="hello"/' file
12
SLePort

Sed-Befehl, der auf MacOS (mindestens OS 10) und Unix gleichermaßen funktioniert (d. H. Er benötigt keine Gnu wie bei Gilles (derzeit akzeptiert)):

sed -e '/CLIENTSCRIPT="foo"/a\'$'\n''CLIENTSCRIPT2="hello"' file

Dies funktioniert in bash und möglicherweise auch in anderen Shells, die den Bewertungsstil "$ '\ n" kennen. Alles kann in einer Zeile sein und in .__ arbeiten. ältere/POSIX sed-Befehle. Wenn möglicherweise mehrere Zeilen mit CLIENTSCRIPT = "foo" (oder Ihrem Äquivalent) übereinstimmen und Sie die zusätzliche Zeile nur beim ersten Mal hinzufügen möchten, können Sie sie wie folgt überarbeiten: 

sed -e '/^ *CLIENTSCRIPT="foo"/b ins' -e b -e ':ins' -e 'a\'$'\n''CLIENTSCRIPT2="hello"' -e ': done' -e 'n;b done' file

(Dies erzeugt eine Schleife nach dem Zeileneinfügungscode, der nur den Rest der Datei durchläuft, ohne zum ersten sed-Befehl zurückzukehren).

Möglicherweise stellen Sie fest, dass ich dem übereinstimmenden Muster ein '^ *' hinzugefügt habe, falls diese Zeile beispielsweise in einem Kommentar angezeigt wird oder eingerückt ist. Es ist nicht zu 100% perfekt, deckt jedoch einige andere Situationen ab, die wahrscheinlich häufig sind. Passen Sie nach Bedarf an ...

Diese beiden Lösungen umgehen auch das Problem (für die generische Lösung zum Hinzufügen einer Zeile), dass, wenn Ihre neu eingefügte Zeile unversehrte Backslashes oder kaufmännische Und-Zeichen enthält, diese von sed interpretiert werden und wahrscheinlich nicht dasselbe wie der \n ist - z . \0 wäre die erste übereinstimmende Zeile. Dies ist besonders praktisch, wenn Sie eine Zeile hinzufügen, die aus einer Variablen stammt, in die Sie vorher alles mit $ {var //} oder einer anderen sed-Anweisung usw. entgehen lassen müssen.

Diese Lösung ist in Skripten etwas unordentlich (das Anführungszeichen und\n ist jedoch nicht leicht zu lesen), wenn Sie den Ersetzungstext für den Befehl a nicht am Zeilenanfang setzen möchten, beispielsweise in einer Funktion mit eingerückten Zeilen. Ich habe ausgenutzt, dass $ '\ n' von der Shell als Newline ausgewertet wird und nicht in regulären '\ n' Werten mit einfachen Anführungszeichen.

Es wird zwar lang genug, aber ich denke, dass Perl/awk aufgrund der Lesbarkeit gewinnen kann.

5
Breezer

Ich musste mich kürzlich damit befassen, aber nicht nur für eine Datei, sondern für mehrere verschiedene Dateien, die ich einfach nicht von Hand erstellen konnte. Also musste ich ein Skript dafür finden.

Skript-Download: kinglazy-autoinsert.sh

Verwendungszweck:

kinglazy-autoinsert.sh (list_file) (pattern_file)

Erklärung der Parameter:

list_file = Dies ist die Datei, die den absoluten Pfad der Liste der Dateien enthält, die Sie bearbeiten möchten

pattern_file = Dies ist die Datei, in der Sie das Muster (in der ersten Spalte) angeben, unter dem Sie neuen Text hinzufügen möchten. Der neue Text, der unter dem Muster hinzugefügt werden soll, wird in der zweiten Spalte angegeben. Und das ist es auch schon!

Dieses Skript spart Zeit und hilft Ihnen, die Arbeit mit dem geringsten Aufwand zu erledigen.

Abhängigkeiten: Keine

0
Blessed

Ich hatte eine ähnliche Aufgabe und konnte die oben genannte Perl-Lösung nicht zum Laufen bringen.

Hier ist meine Lösung:

Perl -i -pe "BEGIN{undef $/;} s/^\[mysqld\]$/[mysqld]\n\ncollation-server = utf8_unicode_ci\n/sgm" /etc/mysql/my.cnf

Erklärung:

Verwendet einen regulären Ausdruck, um in meiner Datei /etc/mysql/my.cnf nach einer Zeile zu suchen, die nur [mysqld] enthält und durch ersetzt wurde

[mysqld] collation-server = utf8_unicode_ci

die collation-server = utf8_unicode_ci-Zeile effektiv nach der Zeile mit [mysqld] hinzufügen.

0
Caleb

Die awk-Variante:

awk '1;/CLIENTSCRIPT=/{print "CLIENTSCRIPT2=\"hello\""}' file
0
Corentin Limier

Vielleicht etwas spät, um eine Antwort zu posten, aber ich fand einige der oben genannten Lösungen etwas umständlich. 

Ich habe den einfachen Stringwechsel in sed ausprobiert und es hat funktioniert:

sed 's/CLIENTSCRIPT="foo"/&\nCLIENTSCRIPT2="hello"/' file

& sign gibt die übereinstimmende Zeichenfolge an und dann fügen Sie\n und die neue Zeile hinzu.

Wie bereits erwähnt, wenn Sie es vor Ort tun möchten:

sed -i 's/CLIENTSCRIPT="foo"/&\nCLIENTSCRIPT2="hello"/' file

Etwas anderes. Sie können mit einem Ausdruck übereinstimmen:

sed -i 's/CLIENTSCRIPT=.*/&\nCLIENTSCRIPT2="hello"/' file

Hoffe das hilft jemandem

0
siwesam