ubuntuusers.de

Spalte oder Zeile Löschen [Perl?Bash?]

Status: Ungelöst | Ubuntu-Version: Ubuntu 8.04 (Hardy Heron)
Antworten |

edwin7

Anmeldungsdatum:
30. Mai 2007

Beiträge: 102

Hallo,

Ich habe eine Tabelle mit 15 GB Groß. Es ist leider zu groß, um diese Tabelle zu bearbeiten. Es hat ungefähr 100.000.000 Zeilen.

Deshalb will ich einige Spalten oder Zeilen ausfiltern (eventuell mit bash oder perl??).

Meine Tabelle sieht beispielweise folgendermaßen aus:

    Zeit Vorname Nachname Adresse Telefon Email
1  Montag Anton   Mühlmeyer Berlin 002934   gogemail@hotmail.com

2  Mittwoch Michael Schröder München 29348  baba@hotmail.com


... usw
achtung: Die Zeilenummer sind auch in der Tabelle drin.

Frage:

1. Wie kann ich die Spalten löschen?(z.B. Die Spalten Telefon und Vorname)?

2. Wie kann ich eine Zeile mit einem bestimmten Strings löschen (z. B. die Zeile mit Nachname Schröder löschen)?

Vielen Dank,

Edwin

Marc_BlackJack_Rintsch Team-Icon

Ehemalige
Avatar von Marc_BlackJack_Rintsch

Anmeldungsdatum:
16. Juni 2006

Beiträge: 4694

Wohnort: Berlin

Lerne Perl oder Python und dann bearbeite die Datei wie gewünscht. Zeilenweise natürlich.

Aus der Datei selbst kannst Du nichts löschen bzw. ist das nicht zu empfehlen, Du wirst "Filter" schreiben müssen, die die Datei einlesen und die veränderten Daten in eine neue Datei schreiben.

Falls Du Dich für Python entscheiden solltest, schau mal ins csv-Modul aus der Standardbibliothek.

Alternativ könnte man die Daten auch in eine Datenbank importieren und entsprechende Anfragen stellen.

user_unknown

Avatar von user_unknown

Anmeldungsdatum:
10. August 2005

Beiträge: 17622

Wohnort: Berlin

100 Mio Zeilen mit Emailadressen? Bist Du ein Spammer? Was hast Du dafür bezahlt? ☺

edwin7

(Themenstarter)

Anmeldungsdatum:
30. Mai 2007

Beiträge: 102

Hallo Mark,

Danke für deine Antwort.

Leider bin ich damit überfordert. Deshalb frage ich hier in Forum, ob jemand mir helfen kann. Ich überhaupt keine Erfahrung mit Python und Perl.

Ich weiß nicht, ob Datenimportierung in DB sich lohnt. Hat jemand Erfahrung mit einer solchen großen Datei? in MYSQL?

edwin7

(Themenstarter)

Anmeldungsdatum:
30. Mai 2007

Beiträge: 102

Nein. Es ist nur ein Beispiel. Ich wollte nur zeigen, dass ich viel Spalten habe.

edwin7

(Themenstarter)

Anmeldungsdatum:
30. Mai 2007

Beiträge: 102

Ich habe zwar die gefunden:

Unter Windows -(DOS-Fenster will "" haben):

 C:\Temp> perl -nle "print join \"\t\", (split)[0..6]" daten.txt

Unter Unix (einfacher):

 $> perl -nle 'print join "\t",(split)[0,2,4,5]' daten.txt

Die Werte in Klammern [0..6] bzw. [0,3,5,6]
sagen, welche Spalten genommen werden sollen
(Zählung beginnt bei Null).

Aber das Problem ist, dass die Spaltentitelreihenfolge nicht mehr richtig.

z. B.

  Vorname  Adresse Telefon Email
 Montag    Mühlmeyer Berlin 002934   gogemail@hotmail.com

 Mittwoch  Schröder München 29348  baba@hotmail.com

dh. Diese Code liest die Zeilennummer als ersten Spalte mit dem Titel "Zeit".

Die Codes verstehe ich leider nicht =P

Übrigens, ich kann die Datei nicht mit Editor öffnen, weil ich vermutlich zu wenig RAM habe ( Es dauert ewig, zu öffnen). D.h. Ich kann nicht einfach die Datei mit Editor öffnen und eine Spaltenname für die Zeilennummer zusätzlich schreiben.

Marc_BlackJack_Rintsch Team-Icon

Ehemalige
Avatar von Marc_BlackJack_Rintsch

Anmeldungsdatum:
16. Juni 2006

Beiträge: 4694

Wohnort: Berlin

Da das Format der ersten Zeile von den restlichen abweicht musst Du die extra behandeln. Selbst wenn das mit einem Perl-Einzeiler in der Shell ginge, sollte man besser ein "ordentliches" Skript schreiben, also in mehreren Zeilen und vielleicht auch mit Kommentaren was man da macht.

Ich denke um eine Programmiersprache wirst Du nicht herum kommen.

Wie sind die Spalten eigentlich getrennt? Leerzeichen? Tabs? Ist sichergestellt, dass der Trenner in den Daten selbst nicht vorkommt? Rein aus paranoia würde ich wahrscheinlich erst einmal ein Skript drüber laufen lassen, das prüft ob jede Zeile nach dem Aufteilen die gleiche Anzahl von Spalten hat.

Ob sich ein Import in eine Datenbank lohnt, hängt davon ab was und wie oft Du von den Daten abfragen möchtest. Die Menge sollte bei einer ordentlichen Datenbank kein Problem sein, denn gerade für grosse Datenmengen sind Datenbanken ja gedacht.

edwin7

(Themenstarter)

Anmeldungsdatum:
30. Mai 2007

Beiträge: 102

Die Spalten ist mit Leerzeichnen getrennt.

Nur die ersten Zeile hat die Anzahl von Spalten eins weniger.

MrDoubtfire

Anmeldungsdatum:
18. Oktober 2005

Beiträge: 210

Hallo edwin7,

empfehle dir den awk:

awk 'NR > 1 { print $2, $3 }' eingabedatei > ausgabedatei

Die Anweisung "NR > 1" ignoriert die 1. Zeile deiner Datei, d. h. du müsstest am Ende in die Ausgabedatei ggf. manuell eine Überschriftszeile einfügen.
Mit "print" gibst Du an, welche Spalten Deiner Eingabedatei in die Ausgabedatei geschrieben werden sollen ($1 = 1. Spalte ..., $0 wäre die ganze Zeile).

MrDoubtfire

edwin7

(Themenstarter)

Anmeldungsdatum:
30. Mai 2007

Beiträge: 102

Hallo MrDoubtfire,

Danke für deine Antwort. Ich habe nicht ganz verstanden. Wo soll ich die $1 und $0 schreiben?

Lux Team-Icon

Avatar von Lux

Anmeldungsdatum:
10. November 2005

Beiträge: 5152

Wohnort: Grüt (Gossau ZH), Schweiz

edwin7 schrieb:

Ich habe nicht ganz verstanden. Wo soll ich die $1 und $0 schreiben?

Ich würde Dir ebenfalls raten, awk zu benutzen.

$0 referenziert in awk eine ganze Zeile, $1 das erste Element einer Zeile, $2 das zweite Element, $3 das dritte Element, ...

In Deinem Beispiel wäre das:

$1 $2     $3      $4        $5     $6       $7
1  Montag Anton   Mühlmeyer Berlin 002934   gogemail@hotmail.com

Nehmen wir an, Du wolltest nur Namen und Vornamen haben, dann würde das der Aufruf

1
awk 'NR > 1 { print $2, $3 }' eingabedatei > ausgabedatei

erledigen.

Einzelne Suchbegriffe kannst Du ebenfalls ausschliessen.

1
awk 'NR > 1 !/Müller/ && !/Schmidt/ { print $2, $3 }' eingabedatei > ausgabedatei

gibt Dir alle Vornamen und Nachnamen aus von Zeilen, die nicht Müller und nicht Schmidt enthalten.

awk-Skripte kann man auch in Dateien schreiben, das muss nicht alles auf der Kommandozeile passieren.

Gruss

Dirk

edwin7

(Themenstarter)

Anmeldungsdatum:
30. Mai 2007

Beiträge: 102

Danke Lux,

Wie lösche ich jetzt eine Zeile mit einem Bestimmten Wort. z. B. Ich möchte die Zeilen löschen, die den Wort "Berlin" enthalten.

schusch

Avatar von schusch

Anmeldungsdatum:
2. September 2008

Beiträge: 324

Wohnort: Berlin

Zum Löschen geht

1
sed '/Berlin/d' <Eingabe >Ausgabe

am schnellsten. Dies löscht jede Zeile, die Berlin enthält

1
awk '{if ($5 != "Berlin") print}' <Eingabe >Ausgabe

macht das, was du vermutlich willst.

Lux Team-Icon

Avatar von Lux

Anmeldungsdatum:
10. November 2005

Beiträge: 5152

Wohnort: Grüt (Gossau ZH), Schweiz

edwin7 schrieb:

Wie lösche ich jetzt eine Zeile mit einem Bestimmten Wort. z. B. Ich möchte die Zeilen löschen, die den Wort "Berlin" enthalten.

1
awk 'NR > 1 !/Berlin/ { print $2, $3 }' eingabedatei > ausgabedatei

Gruss

Dirk

oliver1804

Anmeldungsdatum:
27. März 2006

Beiträge: 279

Wohnort: Elmshorn

Lux schrieb:

[...]

1
awk 'NR > 1 !/Berlin/ { print $2, $3 }' eingabedatei > ausgabedatei

da denk ich jetzt aber, daß das nur mit && funktionieren kann; also:

awk 'NR > 1 && !/Berlin/ { print $2, $3 }' eingabedatei > ausgabedatei

abgesehen davon hätt ich mal 'ne akademische Frage: wenn es tatsächlich Sinn machen würde, die 1. Zeile bzw. die ersten x Zeilen von der Verarbeitung auszuschließen (hier macht es für die 1. Zeile sicherlich keinen Sinn, da es sich schließlich um die Spaltennamen handelt und damit "Berlin" nicht vorkommt), dann provozier ich doch mittels NR > 1, daß jede Zeile geprüft wird? Wenn sich das so verhält, dann scheint mir das bei der vorhandenen Datenmenge (15 GB) zeitlich ungünstig zu sein. Wäre es da nicht vom Zeitaspekt her besser, die Daten durch ein vorgelagertes Programm wie z.B. sed bereitstellen zu lassen?

Antworten |