Command Line Adventures: Anfügen von nicht vorhandenen Zeilen
Welch sperriger Titel. Aber das Problem kennt wahrscheinlich jeder. Man hat z.B. einen Haufen von Configdateien in einer ggf. verschachtelten Verzeichnisstruktur und will in diese einen neuen Parameter einbauen. Als guter Admin hat man natürlich vorab getestet, wie sich dieser neue Parameter auswirkt. Also gibt es ein paar Configdateien die den Parameter bereits enthalten, andere enthalten ihn noch nicht.
Angenommen, wir möchten die Zeile agent: 1
in unseren Configdateien wissen. Mit grep
ist es ein leichtes herauszufinden, ob sich unser Parameter bereits in einer Datei befindet oder nicht:
grep 'agent: 1' $configdatei
Wird der Wert gefunden, wird er ausgegeben, wenn nicht, gibt es keinen Output. Neben dem Output wird aber auch ein anderer Errorlevel (Exit Status) ausgegeben: 0
wenn grep fündig wird, 1
wenn grep nicht fündig wird. Dies können wir nutzen, um nur im zweifen Fall (nichts gefunden) einen weiteren Befehl auszuführen:
grep 'agent: 1' $configdatei || echo 'agent 1' >> $configdatei
Der Operator ||
sorgt dafür, dass der Befehl echo 'agent 1' >> $configdatei
nur dann ausgeführt wird, wenn der Exit Status von grep 'agent: 1' $configdatei
ungleich 0
ist. Somit ist also sichergestellt dass die Zeile dann eingefügt wird, wenn sie nicht bereits vorhanden ist. Jetzt müssen wir nur noch dafür sorgen dass wir nicht ständig selbst den Wert von $configdatei
manuell anpassen müssen.
Angenommen unsere Configdateien befinden sich in einer Verzeichnisstruktur unterhalb von /barfoo
und haben alle die Dateiendung .conf
, so können wir sie einfach mit folgendem Befehl ausgeben lassen:
find /barfoo -name '*.conf' -print
Damit haben wir die Dateien, die wir verarbeiten wollen und können diese an unseren grep
Befehl übergeben. Hierbei hilft uns xargs
die Werte an die korrekten Stellen einzufügen:
find /barfoo -name '*.conf' -print | xargs -I% bash -c "grep 'agent: 1' % || echo 'agent: 1' >> %"
Das bash -c
ist nötig, weil sich sonst der || echo 'agent: 1
-Part nicht allein auf grep -q -F 'agent: 1' %
beziehen würde, sondern auf den find
-Befehl insgesamt.