doppelte Zeilen löschen

S

Steffen1779

Grünschnabel
Grüße,


habe dieses Board durch gestöbern nach einer Lösung für mein Problem.

Da ich noch nichts passendes gefunden habe hoffe ich das ihr mir helfen könntet.
Was ich hier gefunden habe, brach ab,war nicht aus zu führen oder funzte leider nicht.



HP UX 10.0 -11.11
folgendes:

- Ich möchte 1 Host zusammenstellen die aus ca 20 verschiedenen einzelnen hosts zusammen kommen
- doppelte Einträge sollten gelöscht werden und eine neue Hosts mit allen drin enthaltenden clients geschrieben werden,


Habe mir bereits folgendes Überlegt (schaut ziehmlich verwierend aus, da ich zwar weis was will aber nicht weis wie ich es schreiben soll)

Möchte nach den client Bezeichnung Filtern, wenn der gefilterte Eintrag unterschiedlich ist und noch nicht vorhanden >>> schreiben
, wenn bereits vorhanden nächste Zeile..

setz ein Sort - n vorraus und cat all Host >> host


b=0

for i = 'cat hosts' do (Zeile für zeile abarbeiten)
A=grep $i | awk [print $2] ( nach Client name filtern)
If A ungleich B then (schreibe wenn neu)
$i >> hosts_new
A=B
else

end.


Hoffe hab es verständlich rüber gebracht, das man mir helfen könnte
wenn ihr andere Vorschläge habt immer her damit.


Wie wäre es mit Grep (bei gefunden übergibt er 1 sonst 0) und damit weiter progen?

Danke schon mal für eure Hilfe!!

mfg
 
Werd nicht so richtig schlau aus Deinem Post, aber Du könntest Dir mal uniq anschauen.

dirty hack:

Code:
awk '{print $2}' hosts > file 
sort file | uniq > neue_hosts
 
Zuletzt bearbeitet:
Hallo
Ich bin nicht sicher, ob ich dich richtig verstehe.
Aber wenn du mehrere Dateien hast, in denen simpel die Hostnamen stehen und du daraus die kleinste Schnittmenge suchst:
Würde ich das mit perl machen:

Code:
perl -anle '$h{$_}++ for(@ARGV);END{map{print $_ }(keys %h)}' hostliste1 hostliste2...>newhostliste

Gruß Wolfgang
 
danke ,
habe mich vermutlich miss verständlich ausgedrückt,

Ich Habe von ca 20 Server die Hosts genommen , diese sollen zu einer großen hosts werden.

dabei wurden die Einträge der clients fast immer unterschiedlich geschrieben da kein format da war.. das heist..
mal lehrzeichen mehr, mal komentar verschoben etc.

Uniq erkennt diese Einträge immer als verschieden an.. daher der weg über den client namen.



Ich Möchte alle möglichen clients der 20 verschiedenen hosts in 1 einzigen Hosts zusammen fassen, dabei soll /darf kein Eintrag doppelt sein.

Denke ich müßte die IP oder den Namen als Bezugs punkt nehmen,
da ich nicht stumpf "uniq" oder "suchen/löschen" nehmen kann,

Sind ca 400 clients die zum teil vorher scho in fast jede hosts in verschiedene Schreibweisen-Ausführungen vorhanden waren, daher ein script.
Geht mir eher um prinzip.. es muss doch möglich sein

Die schreibweise in der hosts :

IP <tab> clientname<tab> #komentar
 
Zuletzt bearbeitet:
Wie sehen die hosts denn aus. Poste mal bitte Beispiele.
 
danke für schnelle antworten :P hab ja mal übel Hoffnung auf eine Lösung

wie oben schon beschrieben schauen die hosts in der Form aus..
Leider durch Jahrelanger umherschlampen, "versaut" .

Original eine normale Hosts halt. sind nicht jeden system gleich?

Ip <tab> Client-Name < tab> # kommentar



xx.xxx.xxx.001 < tab> test1 <tab> # Testserver
xx.xxx.xxx.002 <tab> User2 <tab> # benutzer


etc etc etc

Die IP und client-name "muss" immer gleich sein.. nur erkennt uniq es teilweise als unterschiedlich ein durch .. doppelt tab. komentar eingerückt etc


mfg
 
Auf die Schnelle (auf wolfgangs Einzeiler aufbauend)

skript.pl:
Code:
#!/usr/bin/perl

for (<>) {
	if (/^[^#]/) {
		chomp;
		@line = split "\t", $_;
		@line2 = split "#", $_;
		$h{"$line[0]"} = $line2[0]
	}
}

map {print "$h{\"$_\"}\n"} (keys %h)

und anschliessend so aufrufen

Code:
cat hosts | skript.pl > neue_hosts

edit:
Steffen1779 schrieb:
...
Original eine normale Hosts halt. sind nicht jeden system gleich?
...

Kann schon sein, war zu faul zum nachschauen ;)
 
Zuletzt bearbeitet:
Vielen Dank!

mir gefählt die ganze Problematik und wollte mich noch weiter damit beschäftigen.

Würde es dir was aus machen, kurz dahinter zu schreiben, was jede einzelne Zeile in dein script bewirgt um es nach zu voll ziehen?

Möcht es gern verstehen, einfach benutzen ist nicht.

Danke im Vorraus für Mühe
 
Hallo
Naja dann eben erst normalisieren, oder wenn es bei perl bleiben darf:
Code:
[b]perl -anle '$h{$F[0]}=$F[1] for(@ARGV);END{map{print "$_\t$h{$_}"}(keys %h)}' hostliste1 hostliste2...>newhostliste[/b]

Perl sollte wenigstens portable sein.

Sonst vorher mit tr -s "\t" alle doppelten \t usw raus , dann mit sed alle Kommentare weg.

Gruß Wolfgang
 
Code:
#!/usr/bin/perl # shebang

# für jede Zeile, die aus dem StandardIn kommt (über die Pipe)
# Bsp: "123.456.789.0 myhost.mydomain myhost # Kommentar"
for (<>) {          

# Nur für Zeilen, die keine Kommentare sind (beginnend mit #), führe folgendes in {} aus
	if (/^[^#]/) {

# Entferne letztes Zeichen, falls es ein \n ist (newline)
		chomp;

# Splittet die Zeile (Hilfsvariable $_) an den Tabs "\t" und ordnet das Array @line zu
# $line[0] = "123.456.789.0", $line[1] = "myhost.mydomain"...
		@line = split "\t", $_;

# Splittet die Zeile (Hilfsvariable $_) an den # und ordnet das Array @line2 zu
# Dient dazu, den Kommentar abzutrennen
# $line2[0] = "123.456.789.0 myhost.mydomain myhost", $line2[1] = "Kommentar"
		@line2 = split "#", $_;

# Baut ein Hash mit Schlüssel "123.456.789.0" und 
# Wert "123.456.789.0 myhost.mydomain myhost"
# Wenn der Schlüssel, also die ips, doppelt vorkommen, wird nur der letzte Wert 
# gespeichert, da die Schlüssel eindeutig sind
		$h{"$line[0]"} = $line2[0]
	}
}

# Gebe zu jedem Schlüssel den Wert aus
map {print "$h{\"$_\"}\n"} (keys %h)

oder Wolfgangs Lösung nehmen, gibt ja mehrere ;)
 
Zuletzt bearbeitet:
Thx für eure Mühe, werde Morgen es sofort mal ausprobieren und ein
Feedback geben!


mfg
Steffen
 
Hallo

Zu meinem Einzeiler siehe
perldoc perlrun
Die Option -a stellt das magische Array @F bereit, in welches die reingereichte Zeile $_ am
Seperator -F [default \s] gesplittet wird.

-F kann dabei auch angegeben werden.

Dann speichere ich das in einem Hash verwende das erste feld als key und das zweite als value.
Am Ende geb ich alle Key-Value aus.

Gruß Wolfgang
 
so, feedback time

beide Programme brachen leider beim ausführen ab,
woran es nun genau lag kann ich nicht sagen, denke aber hatte was damit zu tun das er lehrzeichen fand un kein Tab (wenn ich das Progi richtig verstanden habe) teilweise.



Hättet ihr vielleicht eine "HP-UX KSH skript Shell im Angebot für solche Zwecke?



Läst sich für mich wenn es doch nicht klapt leichter nach vollziehen und fehler finden.

(hab nu sortiert und wegen zuviel zeit investiert erst ein mal per hand gemacht, geht mir im moment nur das es auch mit einen Skript funktionieren muss)

mfg
 
Perl ist unabhängig von der Shell. Vielleicht solltest Du Wolfgangs Tipp über das Löschen doppelter Tabs nutzen. Ausserdem könntest Du in meinem Skript mit den Splitter spielen, also aus "\t" ein " " machen.
 
Hallo

echo -e " abc de \t f"|perl -anle 'print $F[0]'
abc
echo -e "abc de \t f"|perl -anle 'print $F[0]'
abc
echo -e "\tabc\t de \t f"|perl -anle 'print $F[0]'
abc
echo -e "\t \t abc\t de \t f"|perl -anle 'print $F[0]'
abc

Wie du siehst splittet perl das an an /\s+/.
s ist dabei Space und Tab und Newline.
Egal wie häufig die vorkommen, es wird sauber gesplittet.
Dein Problem hat mit Sicherheit eine andere Ursache.
Du hättest ja mal zwei Dateien direkt reinreichen können, und das Ergebnis zu beobachten.

Was kam denn für eine Fehlermeldung?

Gruß Wolfgang
 

Ähnliche Themen

Keine grafische Oberfläche (Debian Installation)

Prblem mit zeilenweises auslesen von Datei und schreiben nach mysql

CSV Datei mit sed manipulieren/optimieren/ergänzen

Probleme mit sed: im Text eine Zeile in Großbuchstaben ?

skript zum löschen doppelter dateien

Zurück
Oben