it-swarm.com.de

Wie füge ich der Mitte einer Datei eine Textzeile mit bash hinzu?

Ich versuche, der Mitte einer Textdatei in einem Bash-Skript eine Textzeile hinzuzufügen. Ich versuche insbesondere, meiner /etc/resolv.conf -Datei einen Nameserver hinzuzufügen. Wie es aussieht, sieht resolv.conf so aus:

# Generated by NetworkManager
domain dhcp.example.com
search dhcp.example.com
nameserver 10.0.0.1
nameserver 10.0.0.2
nameserver 10.0.0.3

Mein Ziel ist es, nameserver 127.0.0.1 vor allen anderen Nameserver-Zeilen, aber unter jedem darüber liegenden Text hinzuzufügen. Am Ende möchte ich, dass meine resol.conf -Datei so aussieht:

# Generated by NetworkManager
domain dhcp.example.com
search dhcp.example.com
nameserver 127.0.0.1
nameserver 10.0.0.1
nameserver 10.0.0.2
nameserver 10.0.0.3

Wie ist das über ein Bash-Skript möglich? Ist das etwas, was sed oder awk tun kann? Oder wäre ein kreativer Greping zum Wiederherstellen der Datei meine beste Maßnahme?

35
PHLAK

Hier ist eine Lösung mit sed:

$ sed -n 'H;${x;s/^\n//;s/nameserver .*$/nameserver 127.0.0.1\n&/;p;}' resolv.conf

# Generated by NetworkManager
domain dhcp.example.com
search dhcp.example.com
nameserver 127.0.0.1
nameserver 10.0.0.1
nameserver 10.0.0.2
nameserver 10.0.0.3

Wie es funktioniert: Zuerst unterdrücken Sie die Ausgabe von sed mit dem Flag -n. Dann hängen wir für jede Zeile die Zeile an den Laderaum an und trennen sie durch neue Zeilen:

H

Wenn wir an das Ende der Datei kommen (durch $ adressiert), verschieben wir den Inhalt des Speicherbereichs in den Musterbereich:

x

Wenn die erste Zeile im Musterbereich leer ist, ersetzen wir sie durch nichts.

s/^\n//

Dann ersetzen wir die erste Zeile, die mit nameserver beginnt, durch eine Zeile, die nameserver 127.0.0.1 enthält, eine neue Zeile (Ihre Version von sed unterstützt \n möglicherweise nicht. In diesem Fall ersetzen Sie die n durch eine literale Zeile) und die ursprüngliche Zeile (dargestellt durch &)

s/nameserver .*$/nameserver 127.0.0.1\n&/

Jetzt müssen wir nur noch die Ergebnisse ausdrucken:

p
39
brandizzi

Angenommen, Sie möchten direkt nach der search-Zeile einfügen, ist dies viel einfacher:

sed -ie '/^search/a nameserver 127.0.0.1' filename
  • -i: Datei an Ort und Stelle bearbeiten
  • -e: Erlaubt die Ausführung eines Skripts/Befehle innerhalb des sed-Ausdrucks
  • a mynewtext: Befehl, der sed anweist, den Text-Mynewtext nach übereinstimmendem Muster einzufügen
19
Jim Garrison

awk '/^nameserver/ && !modif { printf("INSERT\n"); modif=1 } {print}'

8
Karoly Horvath

Wie wäre es mit etwas wie:

sed -e ':a;N;$!ba;s/nameserver/nameserver 127.0.0.1\nnameserver/' /etc/resolv.conf

(ähnlich wie hier: sed: Muster über zwei Zeilen finden, danach nicht ersetzen )

2
sagi

Hier ist eine Perl-Lösung:

Perl -lne 'if (not $f and /^nameserver/){ print "nameserver 127.0.0.1"; $f=1 }; print' resolv.conf

  • -n Schleife um jede Zeile der Eingabedatei, nicht automatisch jede Zeile drucken

  • -l entfernt Zeilenumbrüche vor der Verarbeitung und fügt sie anschließend wieder ein

  • -e Den Perl-Code ausführen

$f wird als Flag verwendet, um anzuzeigen, dass der Nameserver-String bereits gefunden wurde

0
Chris Koknat

Das könnte für Sie funktionieren:

 sed -e '/nameserver/{x;/./b;x;h;i\nameserver 127.0.0.1' -e '}' resolv.conf

Oder GNU sed:

sed -e '0,/nameserver/{//i\nameserver 127.0.0.1' -e '}' resolv.conf
0
potong