2017-05-01 2 views
1

Ich habe viele Hosts-Dateien. Ich sammle sie von allen Servern und ich füge sie in host_files.txt zusammen und dann muss ich eine Hosts-Datei für alle Server erstellen.Host-Datei eine eindeutige Datei für alle Server

Ich mache diesen Befehl, um eine eindeutige Datei zu erstellen, aber einige Zeilen teilen sich dieselbe IP-Adresse oder denselben Hostnamen. ich versuche

awk '!a[$0]++' host_files.txt 

Hier ist meine host_files.txt

#backup server IPs 
95.23.23.56 
95.23.23.57 

#ftp server IPs 
45.89.67.5 
45.89.67.3 

#apache 
12.56.35.36 
12.56.35.35 

#ftp server IPs 
95.23.23.50 

#apache 
12.56.35.37 

I Ausgabedatei wollen, aber ich brauche

#backup server IPs <= comment line, i need to keep them 
95.23.23.56 
95.23.23.57 

#ftp server IPs <= comment line, i need to keep them 
45.89.67.5 
45.89.67.3 
95.23.23.50 

#apache <= comment line, i need to keep them 
12.56.35.36 
12.56.35.35 
12.56.35.37 

die Kommentarzeile halten bereits:

sort -ur host_files.txt 

cat host_files.txt | uniq > ok_host.txt 

Ich brauche die IP ohne # nur n eed ip adresse bitte helfen Sie mir

Vielen Dank im Voraus

Antwort

1

In GNU awk für die Verwendung von mehrdimensionalen Arrays:

$ awk ' 
/^#/ { k=$0; next }   # group within identical comments, k is key to hash 
/./ { a[k][$1]=$0 }   # remove empty records and hash ips 
END { for(k in a) {   # after everything, output 
      print k 
      for(i in a[k]) 
       print a[k][i] 
    } 
}' file* 
#apache 
12.56.35.35 #apacheprivate 
12.56.35.36 #apachepub 
12.56.35.37 #apachepub 
#ftp server IPs 
45.89.67.3 #ftpssh 
45.89.67.5 #ftpmain 
95.23.23.50 #ftp 
#backup server IPs 
95.23.23.56 #masterbasckup 
95.23.23.57 #agentbasckup 

Der Ausgang ist zufällige Reihenfolge wegen for(k in a), dh. Kommentargruppen und IPs innerhalb von Gruppen haben keine bestimmte Reihenfolge.

+0

@ James Brown thx für Ihre Antwort, aber es funktioniert nicht für mich. Ich versuche "awk" /^#/{k=$0;next}/./{a[k][$1]=$0}END{for(k in a) {print k; für (i in a [k]) print a [k] [i]}} 'host_files.txt Ich habe folgende Fehlermeldung: Syntaxfehler Kontext ist: >>>/^ #/{k = $ 0; next} /./ {a [k] [ <<< –

+0

Haben Sie GNU awk? –

+0

nein ich habe nicht gnu awk –

1

Dies wird in jedem awk arbeiten:

$ cat tst.awk 
/^#/ { key = $0; next } 
NF && !seen[$0]++ { 
    ips[key] = ips[key] $0 ORS 
} 
END { 
    for (key in ips) { 
     print key ORS ips[key] 
    } 
} 

$ awk -f tst.awk file 
#apache 
12.56.35.36 #apachepub 
12.56.35.35 #apacheprivate 
12.56.35.37 #apachepub 

#ftp server IPs 
45.89.67.5 #ftpmain 
45.89.67.3 #ftpssh 
95.23.23.50 #ftp 

#backup server IPs 
95.23.23.56 #masterbasckup 
95.23.23.57 #agentbasckup 

Output um die Verwendung der, in Betreiber aufgrund zufälliger sein wird, wenn das ein Problem ist, ist es nur noch ein paar Zeilen Code zu ändern.

+1

Das ist sehr nett. –

0

Wenn awk keine Voraussetzung ist.

#!/bin/ksh 

cat host_files.txt | while read line ; do 
    [[ $line =~ ^$ ]] && { continue; }    # skip empty lines 
    [[ $line =~ ^# ]] && { group=$line; continue; } # remember the group name 
    print "$group|$line"       # print with group name in front 
done | sort \ 
    | while read line ; do 
     if [[ ${line%\|*} != $last ]]; then   # if the group name changed 
      print "\n${line%\|*}"     # print the group name 
      last=${line%\|*}      # remember the new group name 
     fi 
     print "${line#*\|}"       # print the entry without the group name 
    done 
  • setzten die Gruppennamen vor der Linie
  • Art
  • erkennen Gruppennamen zu ändern und es
  • Druckeintrag ohne Gruppennamen

Mit dem gleichen Konzept drucken mit awk (Vermeidung der While-Schleife in der Shell).

awk ' 
    /^#/ { k=$0; next } 
    /./ { print k "|" $0 } 
' host_files.txt | sort | awk -F '|' '{ 
     if (k != $1) { print "\n" $1; k = $1; } 
     print $2 
    }' - 

Da es kein Array verwendet, würde es aufgrund doppelter Schlüssel keine Zeilen verlieren.

Und, ein bisschen mehr denkend, kann das zweite awk vermieden werden. Hinzufügen des Schlüssels zu jeder Zeile. Für den Header ohne 'x'. Also ist der Header über den Rest sortiert. Entfernen Sie in der Ausgabe einfach den hinzugefügten Sortierschlüssel.

awk ' 
    /^#/ { k=$0; print k "|" $0; next; } 
    /./ { print k "x|" $0 } 
' t18.dat | sort -u | cut -d '|' -f 2 
+0

Ob awk ist eine Anforderung oder nicht, es ist das richtige Werkzeug für den Job. Weitere Informationen finden Sie unter [why-is-using-a-shell-loop-to-process-text-bool-practice-text] (https://unix.stackexchange.com/questions/169716/why-is-using-a-shell) -loop-to-process-text-built-bad-practice) aus einigen der Gründe warum (und auch Google UUOC). –

+0

Sie haben Recht mit der UUOC. Aber es macht den Datenfluss offensichtlicher (Okay, es ist nicht das stärkste Argument). – ULick

+0

wollte nur einen anderen Ansatz hinzufügen, ohne die gesamte Eingabe in den Speicher zu lesen und am Ende zu drucken. Aber zwei awk running und eine Art in der Mitte kann es wert sein. – ULick

Verwandte Themen