dertoni
Anmeldungsdatum: 20. Dezember 2006
Beiträge: 133
Wohnort: /home
|
Hallo zusammen, ich habe zwei Dateien. Eine enthält Adressdaten in Folgender Form (telneu.txt):
Vorname Nachname;Strasse;Ort;PLZ;Telnr;
(Je Zeile ein Datensatz) Die Zweite Datei enthält nur Postleitzahlen (plz.txt). Jetzt möchte ich aus der 1. Datei alle Datensätze, deren Postleitzahlen in der 2. Datei vorkommen. Gedacht hab ich mir das folgendermaßen: #!/bin/bash
USERFILE="$1"
echo "Tu mein bestes...."
sleep 1
touch ausgabe.txt
if [ $# -ne 1 ]; then
echo "call ${0} liste"
exit 1
fi
if [ ! -e ${USERFILE} ]; then
echo "Quelldatei ${USERFILE} existiert nicht"
exit 1
fi
echo "Starte einlesen von Datei: $1"
sleep 3
for line in `cat ${USERFILE}`
do
cat telneu.txt | grep ${line} >> ausgabe.txt
done
echo "Einlesen von $1 beendet, Ausgabe erstellt." Es werden auch entsprechend Datensätze herausgefiltert, nur viel zu wenige und teilweise falsche. Hab ich irgendwo einen Fehler im Script, den ich nicht sehe?
Oder gibts hier irgendwelche mengenbeschränkungen bei cat und grep? Die telneu.txt ist 1.8GB gross... also relativ voll mit Daten 😉 Danke
Toni
|
Lux
Anmeldungsdatum: 10. November 2005
Beiträge: 5152
Wohnort: Grüt (Gossau ZH), Schweiz
|
dertoni schrieb: Es werden auch entsprechend Datensätze herausgefiltert, nur viel zu wenige und teilweise falsche. Hab ich irgendwo einen Fehler im Script, den ich nicht sehe?
Zum Einen vermute ich, dass es es auch Telefonnummern gibt, auf die die Postleitzahlen passen, zum Anderen finde ich Deinen Ansatz "gewöhnungsbedürftig".
Oder gibts hier irgendwelche mengenbeschränkungen bei cat und grep? Die telneu.txt ist 1.8GB gross... also relativ voll mit Daten 😉
Nicht, dass ich wüsste. Kannst Du bitte mal kurz schreiben, wie viele Zeilen die beiden Dateien haben? Gruss Dirk
|
dertoni
(Themenstarter)
Anmeldungsdatum: 20. Dezember 2006
Beiträge: 133
Wohnort: /home
|
Zum Einen vermute ich, dass es es auch Telefonnummern gibt, auf die die Postleitzahlen passen, zum Anderen finde ich Deinen Ansatz "gewöhnungsbedürftig".
Das ist mir auch klar. Aber dass Datensätze fehlen nicht. Ich lass meinen Ansatz auch gerne korrigieren 😉 Die Datei mit den Postleitzahlen hat ca 1000 Zeilen, die andere dürfte so... naja, etwa 60.000.000 Zeilen haben
|
Lunar
Anmeldungsdatum: 17. März 2006
Beiträge: 5792
|
Ich würde das mit einer vernünftigen Programmiersprache lösen (Python, ungetestet):
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34 | #!/usr/bin/python
# -*- coding: utf-8 -*-
from __future__ import with_statement
import sys
import csv
from contextlib import nested
def usage():
progname = os.path.basename(sys.argv[0])
print 'usage: %s postleitzahlen adressen'
sys.exit(1)
def main():
args = sys.argv[1:]
if len(args) != 2:
usage()
postal_code_file, adresses_file = args
with nested(open(postal_code_file, 'rb'),
open(adresses_file)) as (postal, adresses):
codes = set(code.strip() for code in postal)
stdout = csv.writer(sys.stdout, delimiter=';')
for row in csv.reader(adresses, delimiter=';'):
postal_code = row[3]
if postal_code.strip() in codes:
stdout.writerow(row)
if __name__ == '__main__':
main()
|
Die Datei mit den Postleitzahlen wird am Stück gelesen, was die Überprüfung beschleunigt und bei 1000 Zeilen kein Problem sein sollte. Die Adressen werden nur zeilenweise gelesen, um den Arbeitsspeicher nicht zu überfordern. Im Allgemeinen sind einfache Textdateien aber kein geeignetes Format für derart große Datenbanken. Eine vollwertige Datenbank ist da weitaus sinnvoller.
|
Lux
Anmeldungsdatum: 10. November 2005
Beiträge: 5152
Wohnort: Grüt (Gossau ZH), Schweiz
|
dertoni schrieb: Das ist mir auch klar. Aber dass Datensätze fehlen nicht. Ich lass meinen Ansatz auch gerne korrigieren 😉
Zum Ansatz: http://wiki.ubuntuusers.de/Shell/Tipps_und_Tricks#Sinnlose-Verwendung-von-Backticks
Die Datei mit den Postleitzahlen hat ca 1000 Zeilen, die andere dürfte so... naja, etwa 60.000.000 Zeilen haben
Ok, dann würde ich anders vorgehen. Witzigerweise muss ich gerade das gleiche auf der Arbeit machen. Gut, es sind kein PLZ-Daten ... Der schnellste Weg ist der Umweg über eine Datenbank. Wenn es Dich interessiert, erkläre ich gerne, wie ich das mit sqlite machen würde. Gruss Dirk
|
dertoni
(Themenstarter)
Anmeldungsdatum: 20. Dezember 2006
Beiträge: 133
Wohnort: /home
|
Der schnellste Weg ist der Umweg über eine Datenbank
Hab ich mir vorhin auch gedacht und ein wenig herumprobiert. Leider weiss ich nicht mit welchem Zeichensatz die große Datei arbeitet.
Daher bricht mir der copy Befehl in psql mit dem Fehlerhinweis auf die Kodierung ab. Hab ich eine Chance die Kodierung irgendwie auszulesen? Mit einem Texteditor umspeichern fällt leider weg.... wer mag schon 1,8GB aufmachen *g*
|
Lux
Anmeldungsdatum: 10. November 2005
Beiträge: 5152
Wohnort: Grüt (Gossau ZH), Schweiz
|
dertoni schrieb: Hab ich mir vorhin auch gedacht und ein wenig herumprobiert. Leider weiss ich nicht mit welchem Zeichensatz die große Datei arbeitet.
Ich bin gerade für so etwas mittlerweile ein Fan von sqlite (dazu einfach sqlite3 installieren). Das hier ist quick'n'dirty (sqlite3 deinedatenbank.sqlite):
| create table telneu (Vorname_Nachname text, Strasse text, Ort text, PLZ text, Telnr text);
.separator ";"
.import telneu.txt telneu
create index idx_telneu_plz on telneu (PLZ);
create table plz (plz text)
.import plz.txt plz
select * from telneu where plz in (select plz from plz);
|
Daher bricht mir der copy Befehl in psql mit dem Fehlerhinweis auf die Kodierung ab.
Hab ich eine Chance die Kodierung irgendwie auszulesen? Mit einem Texteditor umspeichern fällt leider weg.... wer mag schon 1,8GB aufmachen *g*
vim kann dass. Aber Du kannst natürlich mit
| head -n 100 datei > neueDatei
|
einfach die ersten 100 Zeilen in eine neue Datei schreiben und herum experimentierten.
|
user_unknown
Anmeldungsdatum: 10. August 2005
Beiträge: 17552
Wohnort: Berlin
|
file bigdat.txt
liefert manchmal eine Codierung mit. Mit iconv kannst Du Encodings prüfen. Angenommen Du weißt die Datei enthält den Text "Müller", und die Datei heißt namen.txt, dann rufst Du folgendes Script encoding-finder.sh folgendermaßen auf: 1
2
3
4
5
6
7
8
9
10
11
12
13
14 | #!/bin/bash
#
# (c) GPLv3
#
# In einer Datei einen bekannten (Teil-)String (z.B.: Begrüßung) suchen,
# indem alle Encodings ausprobiert werden.
#
[[ $# -ne 2 ]] && echo "Usage: encoding-finder.sh FILE PATTERN_WITH_UMLAUT_FOR_SURE_IN_FILE" && exit
FILE=$1
PATTERN=$2
for enc in $( iconv -l | sed 's/..$//')
do
iconv -f $enc -t UTF-8 $FILE 2>/dev/null | grep -m 1 $PATTERN && echo $enc
done
|
./encoding-finder.sh namen.txt Müller
Nicht selten findet es mehrere mögliche Kandidaten, dann greift man zum wahrscheinlichsten (ISO-8859-1, CP437 in unseren Breiten) oder prüft mit weiteren Worten, die andere Zeichen außerhalb des Asciiraumes (0-127) benutzen. Bei einer großen Datei (> 100 Zeilen) begrenzt Du die Eingabe aber besser auf einen kurzen Ausschnitt, der die heiklen Zeichen enthält.
|
user_unknown
Anmeldungsdatum: 10. August 2005
Beiträge: 17552
Wohnort: Berlin
|
file bigdat.txt
liefert manchmal eine Codierung mit. Mit iconv kannst Du Encodings prüfen. Angenommen Du weißt die Datei enthält den Text "Müller", und die Datei heißt namen.txt, dann rufst Du folgendes Script encoding-finder.sh folgendermaßen auf: 1
2
3
4
5
6
7
8
9
10
11
12
13
14 | #!/bin/bash
#
# (c) GPLv3
#
# In einer Datei einen bekannten (Teil-)String (z.B.: Begrüßung) suchen,
# indem alle Encodings ausprobiert werden.
#
[[ $# -ne 2 ]] && echo "Usage: encoding-finder.sh FILE PATTERN_WITH_UMLAUT_FOR_SURE_IN_FILE" && exit
FILE=$1
PATTERN=$2
for enc in $( iconv -l | sed 's/..$//')
do
iconv -f $enc -t UTF-8 $FILE 2>/dev/null | grep -m 1 $PATTERN && echo $enc
done
|
./encoding-finder.sh namen.txt Müller
Nicht selten findet es mehrere mögliche Kandidaten, dann greift man zum wahrscheinlichsten (ISO-8859-1, CP437 in unseren Breiten) oder prüft mit weiteren Worten, die andere Zeichen außerhalb des Asciiraumes (0-127) benutzen. Bei einer großen Datei (> 100 Zeilen) begrenzt Du die Eingabe aber besser auf einen kurzen Ausschnitt, der die heiklen Zeichen enthält.
|
dertoni
(Themenstarter)
Anmeldungsdatum: 20. Dezember 2006
Beiträge: 133
Wohnort: /home
|
Danke für eure Antworten. Hätte es jetzt über Postgres gelöst. In psql kann copy mit den Dateien umgehen und in Tabellen importieren.
Leider wurde mir nur die Datei mäßig angeliefert... habe eben bemerkt dass sie unterschliedich viele Spalten enthält... ☹
|