Hinzufügen einer Textzeile zu mehreren Dateien

10

Ich habe also eine Reihe von Dateien in einem Verzeichnis und muss in jede eine Textzeile einfügen. Sie haben im Wesentlichen das folgende Format:


<VirtualHost *:80>
        ServerAdmin gabe@localhost
        DocumentRoot /var/www/test1
        ServerName test1.local
        ServerAlias test1
        <Directory "/var/www/test1">
                Options All
                AllowOverride All
        </Directory>
</VirtualHost>

Und ich möchte vor dem Schließen eine Zeile einfügen

</ VirtualHost>
Etikett. Meine erste Annahme ist, dass ich dies mit sed tun kann, wahrscheinlich mit diesem Tag übereinstimmend und ersetzend. Ich werde jetzt anfangen, dies zu versuchen, aber wenn jemand eine Möglichkeit hat, dies zu tun, würde ich es gerne hören.

gabe.
quelle
Ich werde ehrlich sein, wenn ich sage, dass ich denke, dass dies eher eine Programmieraufgabe ist ... und daher auf SO sein sollte. Ich würde Perl verwenden, um dies zu tun, zumal ich wette, dass es ein Perl-Modul gibt, das zum Parsen und Ändern von Apache-Konfigurationen entwickelt wurde.
Xenoterracide
2
Danke, aber es ist eine Aufgabe, die mit einfachen Unix-Tools leicht zu erledigen sein sollte, daher hier gefragt. Vielen Dank für Ihren Kommentar.
gabe.

Antworten:

10

Etwas wie das:

sed 's/<\/VirtualHost>/yourlinehere\n<\/VirtualHost>/'

funktioniert. Wenn Sie diesen Befehl für viele Dateien wiederholen möchten, können Sie Folgendes tun:

for i in *; do sed -i 's/<\/VirtualHost>/yourlinehere\n<\/VirtualHost>/' "$i"; done

Wahrscheinlich besser (aber ungetestet) dank @ChrisDown:

find . -type f -print0 | while IFS= read -r -d '' filename;\
do sed -i 's/<\/VirtualHost>/yourlinehere\n<\/VirtualHost>/' $filename;\ 
done
lcipriani
quelle
super ... das ist genau das, wonach ich gesucht habe.
gabe.
1
Ls nicht analysieren. Verwenden Sie stattdessen einen Glob. mywiki.wooledge.org/ParsingLs
Chris Down
Sie sind genau @ChrisDown. Bitte verbessern Sie meine Antwort.
lcipriani
Die Wahl eines anderen Charakters als /für den sed-Ausdruck ist sauberer, da Sie dem Schrägstrich nicht entkommen müssen:'s:</VirtualHost>:yourlinehere\n</VirtualHost>:'
Alexander
2

Wenn Sie nichts gegen Perl haben, versuchen Sie:

perl -pi'*.old' -e 's(</VirtualHost>(Your stuff here\n</VirtualHost>)' myfile

Der -iSchalter speichert Ihre alte Datei mit einer .oldErweiterung und druckt auf die aktuelle.

gvkv
quelle
2

Sie können auch "ex" (Befehlszeile vi) verwenden, wenn die gewünschte Bearbeitung sogar etwas kompliziert ist. Beispielsweise möchten Sie das Einfügen nur für eine Instanz von "" durchführen.

Ein Shell-Skript wie dieses kann funktionieren:

for FILENAME in *.whatever  # Need a criteria to glob, or a list of names
do
    ex -s $FILENAME << END_EDITS
/^<\/VirtualHost>/
O " capital-o, not zero
text to insert goes here
.
w!
q
END_EDITS
done

Dieser Ansatz bietet Ihnen die Vorteile von "ex": Finden eines Ortes mit Elaboarte-Mustern und "Cursorbewegungen". Sie können beispielsweise ein Muster suchen und dann die nächste Instanz suchen und dann die Einfügung durchführen. Oder Sie können Text ändern, anstatt nur Einfügungen vorzunehmen. Oder Sie können zwischen Bereichen wechseln. Vergessen Sie nicht, dass Sie mit "ex" "verwenden können." wie die aktuelle Zeile, also. / ^ somepatter / s / blah / foo / wird funktionieren.

Bruce Ediger
quelle
0

Sie können den folgenden einzeiligen Code verwenden, um eine einzelne Zeile oder mehrere Zeilen an einer bestimmten Stelle in einer Datei einzufügen, in Ihrem Fall vor 'VirtualHost'. Der Code sucht im Wesentlichen nach dem Dateinamen (es könnte *. * Sein, wenn Sie die Texte in alle Dateien einfügen möchten) innerhalb des angegebenen Verzeichnisses und seiner Unterverzeichnisse. In den gefundenen Dateien wird nach dem Muster 'VirtualHost' gesucht. Nachdem das Muster gefunden wurde, wird es durch firstline \ nsecondline \ notherlines \ n \ VirtualHost ersetzt. Beachten Sie, dass 'VirtualHost' Teil des zu ersetzenden Textes ist, andernfalls verlieren wir ihn.

find directory/ -name filename -print | xargs sed -i 's|VirtualHost|firstline\nsecondline\notherlines\nVirtualHost|g'
Oufie
quelle