Ich habe eine Datei mit dem Namen hostlist.txt
, die folgenden Text enthält:
host1.mydomain.com
host2.mydomain.com
anotherhost
www.mydomain.com
login.mydomain.com
somehost
host3.mydomain.com
Ich habe das folgende kleine Skript:
#!/usr/local/bin/bash
while read host; do
dig +search @ns1.mydomain.com $host ALL \
| sed -n '/;; ANSWER SECTION:/{n;p;}';
done <hostlist.txt \
| gawk '{print $1","$NF}' >fqdn-ip.csv
Welche Ausgänge zu fqdn-ip.csv
:
host1.mydomain.com.,10.0.0.1
host2.mydomain.com.,10.0.0.2
anotherhost.internal.mydomain.com.,10.0.0.11
www.mydomain.com.,10.0.0.10
login.mydomain.com.,10.0.0.12
somehost.internal.mydomain.com.,10.0.0.13
host3.mydomain.com.,10.0.0.3
Meine Frage ist, wie entferne ich .
das Komma kurz vor, ohne es aufzurufen sed
oder gawk
erneut? Gibt es einen Schritt, den ich in den vorhandenen ausführen kann, sed
oder gawk
Anrufe, die den Punkt entfernen?
hostlist.txt
Ich möchte, dass mein Skript schnell und effizient ist.
shell-script
awk
sed
regular-expression
string
Linoob
quelle
quelle
dig +short
es bei Ihnen nicht funktioniert?Antworten:
Der
sed
Befehl, derawk
Befehl und das Entfernen der Nachlaufzeit können zu einem einzigen awk-Befehl zusammengefasst werden:Oder über mehrere Zeilen verteilt:
Da der
awk
Befehl der Anweisung folgtdone
, wird nur einawk
Prozess aufgerufen. Obwohl Effizienz hier keine Rolle spielt, ist dies effizienter, als mit jeder Schleife einen neuen Sed- oder Awk-Prozess zu erstellen.Beispiel
Mit dieser Testdatei:
Der Befehl erzeugt:
Wie es funktioniert
awk liest implizit seine Eingabe einen Datensatz (Zeile) nach dem anderen. Dieses awk-Skript verwendet eine einzelne Variable,
f
die angibt, ob die vorherige Zeile ein Antwortabschnitt-Header war oder nicht.f{sub(/.$/,"",$1); print $1", "$NF; f=0}
Wenn die vorherige Zeile eine Kopfzeile des Antwortabschnitts war, ist
f
sie true und die Befehle in geschweiften Klammern werden ausgeführt. Die erste entfernt die abschließende Periode aus dem ersten Feld. Der zweite druckt das erste Feld,
, gefolgt von dem letzten Feld. Die dritte Anweisung wirdf
auf Null zurückgesetzt (falsch).Mit anderen Worten fungiert
f
hier als logische Bedingung. Die Befehle in geschweiften Klammern werden ausgeführt, wenn sief
ungleich Null sind (was in awk 'wahr' bedeutet)./ANSWER SECTION/{f=1}
Wenn die aktuelle Zeile den String enthält
ANSWER SECTION
, wird die Variablef
auf1
(true) gesetzt.Hier
/ANSWER SECTION/
dient als logische Bedingung. Es wird als wahr ausgewertet, wenn der Strom mit dem regulären Ausdruck übereinstimmtANSWER SECTION
. Wenn dies der Fall ist, wird der Befehl in geschweiften Klammern ausgeführt.quelle
f
eine beliebige Variable oderf{}
ein expliziter Teil der Funktionalität von awk?f
ist eine beliebige Variable. Sie können die{}
komplexen logischen Bedingungen tatsächlich vorgeben.f
ist nur eine sehr einfache logische Bedingung: Es ist wahr, wenn nicht Null, falsch, wenn Null./ANSWER SECTION/
analog zur Rollef
im ersten Befehl die Rolle der logischen Bedingung gespielt wird. Ich habe die Antwort aktualisiert, um dies zu diskutieren.dig
kann eine Datei mit einer Liste von Hostnamen einlesen und einzeln verarbeiten. Sie können auch festlegendig
, dass alle Ausgaben mit Ausnahme des Antwortbereichs unterdrückt werden sollen.Dies sollte Ihnen die Ausgabe geben, die Sie wollen:
awk
Mit dersub()
Funktion von wird die Literalperiode.
vom Ende des ersten Feldes entfernt. Dann werdenawk
die durch Komma getrennten Felder 1 und 5 gedruckt.HINWEIS: Einträge
hostlist.txt
, die nicht aufgelöst werden, werden vollständig verworfen - sie werden nicht in stdout ODER stderr angezeigt.(Getestet unter Linux und FreeBSD)
quelle
Ändern Sie Ihren Aufruf
gawk
wie folgt:quelle