ubuntuusers.de

Entkommentieren mit sed ohne neue Datei zu schreiben

Status: Gelöst | Ubuntu-Version: Server 12.04 (Precise Pangolin)
Antworten |

chrisrich

Avatar von chrisrich

Anmeldungsdatum:
2. März 2009

Beiträge: 54

Moin moin aus dem Norden!

Meine letzten sed-Versuche sind schon ein paar Monate her und im Netz konnte ich bisher keine Antwort auf meine Frage finden.

Ich erstelle mir gerade ein Shell-Skript, in dem ich unter anderem das entkommentieren einer Zeile von einer Konfigurationsdatei einbeinden möchte. Konkret geht es um ein Skrip zur Installation von Nginx.

Manuell klappt das und auch mit grep finde ich die richtige Zeile:

1
grep cgi.fix_pathinfo=1 /etc/php5/cgi/php.ini

Meine bisherige Idee (inkl. Sicherheitskopie falls etwas schief läuft) ist folgende:

1
2
3
cp /etc/php5/cgi/php.ini /etc/php5/cgi/php.ini.sav;
sed 's/^; cgi\.fix_pathinfo=1/cgi\.fix_pathinfo=1/' /etc/php5/cgi/php.ini > /etc/php5/cgi/php.ini.new;
mv /etc/php5/cgi/php.ini.new /etc/php5/cgi/php.ini

Meine Frage ist nun ob man mittels sed auch innerhalb einer Datei etwas verändern kann, ohne eine Datei neu anzulegen und anschließend in den Namen der alten Datei umzubenennen. Mein Ziel ist es das Skript so kurz und einfach wie möglich zu halten (die Sicherheitskopie halte ich für einen nötigen zusätzlichen Schritt).

Könnte ich also in einer Datei, die (wiein diesem Falle) knapp 1.000 Zeilen hat diese entsprechende Zeile verändern und wieder in sich selbst schreiben?

Danke für die Antworten und entschudligt, wennn ich mich vielleicht etwas umständlich ausdrücke. Ich bin noch dabei mich auf diesem Gebiet einzuarbeiten.

Grüße, Christian

Vain

Avatar von Vain

Anmeldungsdatum:
12. April 2008

Beiträge: 2510

Servus,

chrisrich schrieb:

Meine Frage ist nun ob man mittels sed auch innerhalb einer Datei etwas verändern kann, ohne eine Datei neu anzulegen und anschließend in den Namen der alten Datei umzubenennen.

nein, aber du kannst sed veranlassen, das selbst zu tun. Dazu ist der Parameter „-i“ gedacht.

sed -i 's/.../.../'

Intern schreibt sed aber, soweit ich weiß, nach wie vor in eine neue Datei und nennt die hinterher um. Sieht man hier, die Inode-Nummer ganz vorne ändert sich:

$ l -i bla
1447901 -rw-r--r-- 1 void users 6 Jun 19 14:52 bla

$ sed -i 's/hallo/welt/' bla

$ l -i bla
1448797 -rw-r--r-- 1 void users 5 Jun 19 14:52 bla

chrisrich

(Themenstarter)
Avatar von chrisrich

Anmeldungsdatum:
2. März 2009

Beiträge: 54

Das ging ja schneller als ich gehofft habe. ☺

Wenn ich also -i einfüge und keinen Dateinamen ans Ende setze schreibt sed das quasi in die Datei? Und der Rest der 1.000 Zeilen bleibt unverändert?

RealOrakel

Anmeldungsdatum:
3. November 2009

Beiträge: Zähle...

Hmmm mal ganz blöde gefragt: Du sicherst doch im ersten Schritt die Datei weg. Warum änderst Du den Aufruf nicht von

sed 's/^; cgi\.fix_pathinfo=1/cgi\.fix_pathinfo=1/' /etc/php5/cgi/php.ini > /etc/php5/cgi/php.ini.new

sed 's/^; cgi\.fix_pathinfo=1/cgi\.fix_pathinfo=1/' /etc/php5/cgi/php.ini.sav > /etc/php5/cgi/php.ini

Grüße

Vain

Avatar von Vain

Anmeldungsdatum:
12. April 2008

Beiträge: 2510

chrisrich schrieb:

Wenn ich also -i einfüge und keinen Dateinamen ans Ende setze schreibt sed das quasi in die Datei?

Keinen Dateinamen? Keine Umleitung! 😉

Aber, ja,

sed 's/hallo/welt/' dateiname > foo
mv foo dateiname

lässt sich „verkürzen“ zu:

sed -i 's/hallo/welt/' dateiname

Und der Rest der 1.000 Zeilen bleibt unverändert?

Nun gut, sed tut halt, was du ihm sagst. Wenn deine Operation nur eine Zeile betrifft, ist das so. Kurz: Jo.

track

Avatar von track

Anmeldungsdatum:
26. Juni 2008

Beiträge: 7174

Wohnort: Wolfen (S-A)

chrisrich schrieb:

Wenn ich also -i einfüge und keinen Dateinamen ans Ende setze schreibt sed das quasi in die Datei? Und der Rest der 1.000 Zeilen bleibt unverändert?

Bitte lies es selber nochmal in man sed nach:

-i[SUFFIX], --in-place[=SUFFIX]
    edit files in place (makes backup if extension supplied) 

Das überschreibt also die gelesene Datei mit genau dem, was sonst auf der Kommandozeile ausgegeben würde.

LG,

track

chrisrich

(Themenstarter)
Avatar von chrisrich

Anmeldungsdatum:
2. März 2009

Beiträge: 54

Danke für die Antwort. Hab ich wieder etwas dazugelernt. Und richtig, es heißt ja umleiten ... ich werde mir diesen terminus technicus merken.

In diesem Falle muss ich dann also schreiben:

1
sed -i 's/^; cgi\.fix_pathinfo=1/cgi\.fix_pathinfo=1/' /etc/php5/cgi/php.ini

Noch eine erweiterte Frage:

Kann ich das denn noch weiter verkürzen, in dem ich statt dem Austausch der ganzen Zeile eine Anweisung nur zum entfernen von Semikolon und Leerzeichen schreibe? Ich vermute mal, dass ich noch ein paar mehr Zeilen entkommentieren muss und könnte dann die doppelte Nennung dieser Zeile vermeiden.

rklm Team-Icon

Projektleitung

Anmeldungsdatum:
16. Oktober 2011

Beiträge: 13217

chrisrich schrieb:

Kann ich das denn noch weiter verkürzen, in dem ich statt dem Austausch der ganzen Zeile eine Anweisung nur zum entfernen von Semikolon und Leerzeichen schreibe? Ich vermute mal, dass ich noch ein paar mehr Zeilen entkommentieren muss und könnte dann die doppelte Nennung dieser Zeile vermeiden.

Du hast eigentlich zwei Möglichkeiten:

  1. Du definierst das Suchmuster von s/// entsprechend und benutzt eine Gruppe bei der Einsetzung oder

  2. Du wählst Zeilen per regulärem Ausdruck aus und löscht nur.

1
2
3
4
5
# Variante 1
$ sed -i.bak 's/^ *; *\(cgi\.fix_pathinfo=1\|foo=bar\)/\1/' /etc/php5/cgi/php.ini

# Variante 2
$ sed -i.bak '/^ *; *\(cgi\.fix_pathinfo=1\|foo=bar\)/ s/^ *; *//' /etc/php5/cgi/php.ini

Ciao

robert

chrisrich

(Themenstarter)
Avatar von chrisrich

Anmeldungsdatum:
2. März 2009

Beiträge: 54

Vielen Dank für die Antworten!

Da meine eigentliche Frage bereits beantwortet worden ist habe den Thread schon mal als gelöst markiert.

Zur letzten Antwort:

bedeutet bei

1
sed -i.bak

das .bak, dass automatisch eine Sicherheitskopie geschrieben wird?

Und soll in der zweiten Variante das <s> in

1
<'/^*; *  ... usw'

tatsächlich weggelassen werden? Ich bin auch bei RegEx noch am lernen.

rklm Team-Icon

Projektleitung

Anmeldungsdatum:
16. Oktober 2011

Beiträge: 13217

chrisrich schrieb:

bedeutet bei

1
sed -i.bak

das .bak, dass automatisch eine Sicherheitskopie geschrieben wird?

Was sagt denn "man sed"? 😬 Schau mal, was track schrieb.

Und soll in der zweiten Variante das <s> in

1
<'/^*; *  ... usw'

tatsächlich weggelassen werden? Ich bin auch bei RegEx noch am lernen.

Es ist nicht weggelassen. Das 's' ist nicht Teil des Regulären Ausdrucks sondern ein Kommando.

Ciao

robert

chrisrich

(Themenstarter)
Avatar von chrisrich

Anmeldungsdatum:
2. März 2009

Beiträge: 54

rklm schrieb:

chrisrich schrieb:

bedeutet bei

1
sed -i.bak

das .bak, dass automatisch eine Sicherheitskopie geschrieben wird?

Was sagt denn "man sed"? 😬 Schau mal, was track schrieb.

das hab ich tatsächlich übersehen. Der Beitrag ist mir erst gerade aufgefallen. Zur Endnung habe ich in der man gefunden, dass eine Sicherung erstellt wird "falls Endung angegeben" wird. Damit ist dann also die Endung .bak gemeint, wenn ich das richtig verstehe.

Und soll in der zweiten Variante das <s> in

1
<'/^*; *  ... usw'

tatsächlich weggelassen werden? Ich bin auch bei RegEx noch am lernen.

Es ist nicht weggelassen. Das 's' ist nicht Teil des Regulären Ausdrucks sondern ein Kommando.

Ok, ich werde mir wohl den ganzen Befehlszeilenaufruf von sed noch mal genauer anschauen und besser verstehen müssen.

Ciao

robert

Ich hangel mich übrigens an dieser Anleitung entlang, falls jemand mal diesen Thread findet und eine Anleitung gebrauchen kann:

http://www.howtoforge.de/anleitung/installation-von-nginx-und-php5-mit-mysql-unterstutzung-unter-debian-squeeze/

track

Avatar von track

Anmeldungsdatum:
26. Juni 2008

Beiträge: 7174

Wohnort: Wolfen (S-A)

Zum Lernen von sed würde ich übrigens http://www.tty1.net/sed-tutorium/sed-tutorium.html empfehlen,
und als Nachschlagewerk: http://www.gnu.org/software/sed/manual/sed.html .

LG,

track

chrisrich

(Themenstarter)
Avatar von chrisrich

Anmeldungsdatum:
2. März 2009

Beiträge: 54

Danke für die Links! Werde ich mir anschauen.

Antworten |