2010-12-27 3 views
1

Ich versuche herauszufinden, wie Sie den letzten Eintrag einer Zeichenfolge in mehreren Konfigurationsdateien über einen Server finden. Jede der Saiten werden in der Datei /home/***usernamewouldbehere/public_html/typo3conf/localconf.phpWie finde ich die letzte Instanz einer Einstellung in einer Konfigurationsdatei?

Kurz gesagt - der letzte Eintrag in den Konfigurationsdateien werden in die Datenbank-Server zeigen die Anwendung nutzt - und Wir müssen wissen, welche Konten auf welchen Datenbankserver verweisen.

Während ich so etwas wie diese laufen kann -

grep "$_db_host" /home/*/public_html/conf/localconf.php 

Es ist wirklich nicht viel helfen, weil es uns viel zu vielen Informationen gibt ... und nicht das, was wir wirklich brauchen.

Was ich wirklich wissen muss, ist der letzte Eintrag dieser Zeichenfolge $ _db_host = 'xx'; und sortieren sie in einer Exportdatei aus

Da die Konfigurationsdateien mehrere Einträge aufweisen (Beispiel unten)

$_db_host = 'localhost'; 
$_db_host = '10.0.1.234'; 

Es wäre toll, in einer Datei zur Liste all derer, die den Eintrag für ' localhost ' und dann alle diejenigen auflisten, die den Eintrag für '10 .0.1.234' haben (oder welchen Server es dort gibt), aber selbst wenn ich das manuell machen müsste, wäre das großartig.

Ich bin nicht sicher, wie man es bekommen Awk mit - ... und stecken wirklich

Was ich hoffe, für etwas, das geleitet werden würde als

db_host = localhost /home/username1/www/conf/localconf.php 
db_host = localhost/home/username2/public_html/conf/localconf.php 

db_host= '10.1.2.23' /home/username55/public_html/conf/localconf.php 

folgt der Hoffnung, dass Sie hilft helfen Sie mir :-)

Antwort

2

Ihre Frage ein wenig unklar ist, aber dies ist ein erster Versuch:

grep "$_db_host" /home/*/public_html/typo3conf/localconf.php | \ 
    awk '{ print $1":"$3; }' | awk -F ':' '{ print $3": "$1 }' | sort 

Was das ist ist grep 's für $_db_host Zeilen. Vielleicht möchten Sie eine Regex verwenden, um es robuster zu machen, wenn dort möglicherweise andere Zeichenfolgen mit der Teilzeichenfolge $_db_host vorhanden sind, die Sie nicht abgleichen möchten. Es verwendet dann zwei Durchgänge von awk, um die Zeilen in 'ip';: configfile-Format zu konvertieren. Sie können die Anführungszeichen und das Semikolon bei Bedarf mit Bash-Slicing loswerden, aber wenn das Format nicht streng ist, benötigen Sie eine Regex. Schließlich werden die Ergebnisse so sortiert, dass übereinstimmende IP-Adressen einander folgen (ohne Unterschiede in Anführungszeichen, weshalb Sie sie möglicherweise streichen möchten).

Beispielausgabe:

'10.0.1.234';: /home/foo/public_html/typo3conf/localconf.php 
'localhost';: /home/bar/public_html/typo3conf/localconf.php 
3

Es ist ein wenig unklar, was Sie fordern.Ohne in Perl oder awk Sie vielleicht so etwas wie

grep -H '$_db_host =' /home/*/public_html/typo3conf/localconf.php | tail -n 1 

Oder wenn Sie die letzten in jeder Datei (bash-Syntax) verwenden:

for i in (/home/*/public_html/typo3conf/localconf.php); do 
    grep -H '$_db_host =' $i /dev/null | tail -1 
done 

Wenn Sie möchten, kategorisieren, indem die jeweiligen Werte von $ _db_host Sie können sortieren verwenden (entweder mit oder ohne Schwanz Trick):

grep -H '$_db_host =' /home/*/public_html/typo3conf/localconf.php | sort -t = -k 2,2 

(die Art sagt „=“ als Feldtrennzeichen zu verwenden und dann sortieren nach dem zweiten Feld - dies wird effektiv sortieren um den Wert von $ _db_host, und die -H-Grep-Ausgabe sagt Grep, um den Dateinamen der übereinstimmenden Zeilen am Anfang anzuzeigen.

Hinweis Sie können die Ausgabe der Schleife oben auch:

for i in (/home/*/public_html/typo3conf/localconf.php); do 
    grep -H '$_db_host =' $i /dev/null | tail -1 
done | sort -t = -k 2,2 

Sie können Ihre Werkzeuge mischen oder passen, wie Sie wünschen!

ein weiteres sehr nützliches Werkzeug ist "cut" (mit -d, um das Feldtrennzeichen anzugeben), mit dem Sie den Ausgang auseinanderziehen können.

(Sie können alle diese in Perl zu tun und awk als gut, aber manchmal, vor allem für "one-offs" Shell-Pipelines sind leichter)

+0

hmm k - lass mich versuchen, ein wenig klarer zu sein - und ich werde die Frage auch bearbeiten. Kurz gesagt - müssen Sie nur für alle localconf.php-Dateien auf dem Server wissen, auf die jede Datenbank zeigt - und in der Datei localconf.php können mehrere Einträge von _db_host sein - wir müssen nur die letzten - und auflisten wenn möglich, sortiere sie, damit wir wissen, welche wo zeigen - dh wir haben 40, die auf localhost zeigen und sie auflisten und dann wewe haben 20, die auf den db server 10.0.2.23 zeigen oder wo auch immer ... in der hoffnung hilft –

+0

OK, es klingt wie etwas, basierend auf der letzten Variante in meiner Antwort würde sein, was Sie brauchen - es wird die letzte "$ _db_host" -Zeile aus jeder Datei, und dann wird dies um den Wert von $ _db_host, gruppieren sie für Sie. (Wenn Sie den db_host Wert zuerst wollen, und den "$ _db_host =" von der Ausgabe entfernen möchten, wäre wahrscheinlich am einfachsten ein awk Konstrukt zu verwenden, wie marcog suggeriert) – jsegal

1

Es scheint hier zwei Fragen zu sein:

  1. Listen Sie die Dateien auf, die "$_db_host = 'localhost';" enthalten.

    grep -l '^[ <t>]*$_dbhost[ <t>]*=[ <t>*]'localhost'[ <t>]*;' \ 
         /dev/null /home/*/public_html/conf/localconf.php 
    

    ich <t> bin mit, um anzuzeigen, wo das Skript ein Register enthalten könnte; Sie müssen nicht so vorsichtig sein, wenn Sie sicher sind, dass Ihre Zeilen starr formatiert sind.

  2. Listen Sie den letzten Hostnamen (Adresse) in einer Datei auf, die möglicherweise auch localhost-Einträge enthält (wobei die localhost-Einträge ignoriert werden sollen).

    grep -l '^[ <t>]*$_dbhost[ <t>]*=[ <t>*]'[^']*'[ <t>]*;' \ 
         /dev/null /home/*/public_html/conf/localconf.php | 
    grep -v "'localhost'" | 
    sed 's/:[ <t>]*$_dbhost[ <t>]*=[ <t>]*'\([^']*\)';/ \1/' | 
    awk '{address[$1] = $2} 
        END { for (file in address) { 
           printf "%s %s\n", file, address[file]; 
          } 
         }' | sort 
    

    Die grep -v und sed Befehle kombiniert werden könnten, aber es ist einfacher zu verstehen, wenn sie nicht sind. Wenn dieses Skript nicht sehr oft verwendet wird, ist es wahrscheinlich nicht wichtig, sich über die Leistungseinbußen Gedanken zu machen.

    Die erste grep ist eine geringfügige Anpassung der Antwort auf Q1; Es erzeugt eine Liste von Dateinamen (die Suche nach '/ dev/null' findet nichts, stellt aber sicher, dass der Name immer noch aufgelistet ist, wenn es nur eine Datei localconf.php gibt). Die zweite grep beseitigt Localhost-Zeilen. Der sed Befehl entfernt die Trümmer und lässt nur den Dateinamen und den Hostnamen in zwei durch Leerzeichen getrennten Feldern zurück, genau wie awk seine Daten mögen. Der Befehl awk verwendet ein assoziatives Array, das mit dem Dateinamen versehen ist, um den letzten Eintrag in einer Datei aufzuzeichnen. Die Zuweisung überschreibt immer einen vorherigen Wert. Der END-Block druckt dann alle Dateinamen und den entsprechenden letzten in der Datei gesetzten Wert $_db_host aus. Das sort listet nur die Dateien in einer deterministischen Reihenfolge auf; Die for Schleifenreihenfolge ist nicht deterministisch. Sie könnten das awk Skript auf eine oder zwei Zeilen reduzieren - ich streiche es über 5, um die begrenzte Linienbreite in SO aufzunehmen.


Adressierung Kommentar:

Wir können meine 'Teil 2' Antwort anzupassen - und die Single-Quote vs doppelte Anführungszeichen Problem zu beheben, dass Sie die Shell-Fehler gibt.

Bearbeitet: Die unerwünschte -l Option wurde gelöscht und eine fehlende $ wiederhergestellt.

grep "^[ <t>]*\$_dbhost[ <t>]*=[ <t>*]'[^']*'[ <t>]*;" \ 
     /dev/null /home/*/public_html/conf/localconf.php | 
sed "s/:[ <t>]*\$_dbhost[ <t>]*=[ <t>]*'\([^']*\)';/ \1/" | 
awk '{address[$1] = $2} 
    END { for (file in address) { 
       printf "%s %s\n", file, address[file]; } }' | 
sort 

Dies läßt den localhost-Eintrag in der Liste. Ich habe geändert, was zuvor einfache Anführungszeichen um das grep Regex und das sed Skript in doppelte Anführungszeichen umgab. Das bedeutet, dass es notwendig ist, die $ Symbole zu entkommen.


Ignorieren Registerkarten:

grep "^ *\$_dbhost *= '[^']*' *;" \ 
     /dev/null /home/*/public_html/conf/localconf.php | 
sed "s/: *\$_dbhost *= *'\([^']*\)';/ \1/" | 
awk '{address[$1] = $2} 
    END { for (file in address) { 
       printf "%s %s\n", file, address[file]; } }' | 
sort 

Getestet habe ich diese eigentlich mit einer Reihe von trivialen Dateien anstelle der großen langen komplexen/home/*/public_html/... Pfadnamen - es funktionierte OK.

JL: cat f1 
$_dbhost = 'localhost'; 
JL: cat f2 
$_dbhost = 'localhost'; 
$_dbhost = '9.12.23.34'; 
JL: 

Etc.

+0

sehr nah - kurz 1 Hauptfrage muss ich kenne den letzten Eintrag in jedem /home/*/public_html/conf/localconf.php für db_host = 'xxxxx'; (Wobei xxxxx könnte entweder lokale Host und/oder eine IP-Adresse) ich natürlich müssen wissen, ob sie localhost sind oder eine andere ip Ich lief, was Sie setzen - aber es errored out Angabe bash: t: Nein solche Datei oder Verzeichnis Ich werde es ein paar Versuche geben - aber jede zusätzliche Hilfe wird sehr geschätzt - die Dateien sind alle ziemlich starr - was sehr hilfreich –

+0

Ich denke, Sie haben die nächste Antwort - leider immer noch Fehler mit der bash: t: Keine solche Datei oder Verzeichnis :-( Die Datei ist ziemlich Standard - wie würde das aussehen, wenn wir die Tabstopps loswerden würden? Danke nochmal, übrigens –

0

Sie Regex-Fu ist schwach.

> cat localconf.php 
$_db_host = '10.0.1.234'; 

> grep -oP '(?<=\$_db_host = '\'').*(?='\'';)' localconf.php 
10.0.1.234 

> grep --version | head -n 1 
GNU grep 2.5.4 
Verwandte Themen