rumpelstielzchen987
Goto Top

alle zeilen mit bestimmten informationen aus einer text datei filtern

zeilen mit bestimmten infos in einer txt finden und in eine neue txt eeinfügen

Nehmen wir an, ich habe eine datei mit 200000 zeilen.
einen sehr langen kontoauszug von paypal beispielsweise.
in jeder zeile stehen informationen wie verwendungszweck, absenderemail, betrag, empfängeremail (falls mehrere emailadressen auf einen account verlinkt sind).
diese daten stehen pro überweisung in einer zeile hintereinander, wahlweise durch ; oder {tabstop} getrennt.
nun möchte ich aus dieser datei mit einer batchdatei zum Beispiel alle absenderemailadressen derer, die einen betrag von 1€ mit dem verwendungszweck Spende an die emailadresse spendenkonto1@fff.ff herausfiltern um diesen leuten dann eine danksagung zukommen zu lassen. wenn ich die emailadressen habe, kann ich ja bcc benutzen um alle zu erreichen.
dazu möchte ich erst aus dem kontoauszug alle zeilen mit diesen kriterien filtern und darüber dann eine batch laufen lasssen die alle emailadressen aufschreibt die ungleich der empfängeremailadresse sind.

ganz einfach also. ich nehme an, das kann man mit find machen, allerdings habe ich noch nichts näheres dazu gefunden.

ich hoffe ihr könnt mir helfen.

Content-ID: 50429

Url: https://administrator.de/contentid/50429

Ausgedruckt am: 13.11.2024 um 00:11 Uhr

bastla
bastla 01.02.2007 um 14:23:59 Uhr
Goto Top
Hallo rumpelstielzchen987!

Im Prinzip würde für Teil 1 (das Ausfiltern) folgende Zeile reichen:
find /i "spendenkonto1@fff.ff" < "LangeListe.txt" > "KurzeListe.txt"  
Für den Rest bräuchte ich noch mehr Informationen über den Satzaufbau.

Grüße
basta
rumpelstielzchen987
rumpelstielzchen987 01.02.2007 um 14:38:23 Uhr
Goto Top
wie gesagt:

zeile 1: (diese zeile enthält dei überschriften der spalten)
zeile 2:...(Empfängeradresse)...(Absenderadresse)...(Zahlungsbetrag)...(Verwendungszweck)...
zeile 3:...spendenkonto1@fff.ff...absender@fff.ch...1 EUR...Spende
zeile 4:...spendenkonto2@ggg.gg...alberteinstein@sanatorium-berlin-sued.de...90000000 EUR...Danksagung fuer deine Hilfe bei Entwicklung der Relativitätstheorie
zeile 5:...spendenkonto1@fff.ff...absender@fff.ch...1 EUR...Spende
...
zeile 9827:...spendenkonto1@fff.ff...absender@fff.ch...1 EUR...Spende
...

danke für die schnelle antwort.

ich möchte jetzt erst alle zeilen extrahieren die
an spendenkonto1@fff.ff
Zahlungsbetrag 1 EUR
Verwendungszweck Spende
enthalten.
Dass die Zeile alle Kriterien erfüllt, ist wichtig. Ich kann es ja über Filtervorgänge abhandeln. Vielen dank also für deine Antwort. Die hat schon sehr geholfen.

wo wir grad dabei sind, wäre bitte jemand so nett, mir zu erklären, wie die findparameter so funktionieren? wenn ich in cmd frage heißt es immer, help, /h, -help, oder -h seinen falsche parameter.
Biber
Biber 01.02.2007 um 14:43:59 Uhr
Goto Top
Moin rumpelstielzchen987,

am CMD-Prompt ist die übliche Syntax.
help find
- oder -
find /?
[einige Programme, meistens die portablen/portierten haben auch *nix-artige Schalter /h oder --h oder -help. Aber Srandard ist...s.o.]

HTH Biber
bastla
bastla 01.02.2007 um 14:48:35 Uhr
Goto Top
Hallo rumpelstielzchen987!

Bleiben wir noch bei den einfachen Sachen face-wink

Mehrfaches Ausfiltern könntest Du über eine Kette machen:
find /i "spendenkonto1@fff.ff" < "LangeListe.txt" > "KurzeListe1.txt"  
find /i "1 EUR" < "KurzeListe1.txt" > "KurzeListe2.txt"  
find /i "spende" < "KurzeListe2.txt" > "Fertig.txt"  
Die entstehenden Zwischendateien lassen sich, wenn nicht mehr benötigt (etwa zu Debug-Zwecken), per "del KurzeListe*.txt" rückstandslos entsorgen.

Grüße
bastla
rumpelstielzchen987
rumpelstielzchen987 01.02.2007 um 14:51:45 Uhr
Goto Top
das mit den mehreren schritten hatte ich schon begriffen, danke.
danke aber für die erläuterung wie man find-hilfe aufruft^^ (mit help find, nicht find help o.ä.)
bastla
bastla 01.02.2007 um 15:11:50 Uhr
Goto Top
Hallo rumpelstielzchen987!

Wenn Du ";" als Trennzeichen hast, könnte es so weitergehen:
for /f "tokens=2 delims=;" %i in ('type "Fertig.txt"') do echo %i>> "Adressliste.txt"  
Falls Du eine Batch-Datei daraus machen willst, musst Du jeweils %%i statt %i schreiben.

Grüße
bastla
rumpelstielzchen987
rumpelstielzchen987 01.02.2007 um 15:54:48 Uhr
Goto Top
ok. die zeilen mit der empfängeradresse und allen anderen nötigen kriterien habe ich jetzt isoliert. wie kann ich daraus jetzt alle emailadressen herausfiltern, in eine datei schreiben und meine emailadresse daraus löschen? ich möchte das auch hinbekommen wenn ich nicht die ;s abzähle nach denen die emailadresse steht. auch wenn das wohl am einfachsten wäre.

das müsste dann sowas sein wie,
finde in datei3.txt alle wörter die ein @ enthalten und schreibe sie in datei4.txt
lösche aus datei4.txt alle wörter die meineaddy1@g.g lauten
lösche aus datei4.txt alle wörter die meineaddy2@g.g lauten
lösche aus datei4.txt alle wörter die meineaddy3@g.g lauten
lösche aus datei4.txt alle wörter die meineaddy4@g.g lauten
lösche aus datei4.txt alle wörter die meineaddy5@g.g lauten
lösche aus datei4.txt alle wörter die meineaddy6@g.g lauten
lösche aus datei4.txt alle wörter die meineaddy7@g.g lauten
bastla
bastla 01.02.2007 um 16:01:15 Uhr
Goto Top
wie kann ich daraus jetzt alle emailadressen herausfiltern, in eine datei schreiben
alle zeilen mit bestimmten informationen aus einer text datei filtern
und meine emailadresse daraus löschen?
find /v /i "meinemail@abc.ef" < "Adressliste.txt" > "NurAndereAdressen.txt"  

Grüße
bastla

[Edit] Zusatzanforderung ("ich möchte das auch hinbekommen wenn ...") beim Erstellen dieses Kommentars noch nicht vorhanden. [/Edit]
rumpelstielzchen987
rumpelstielzchen987 01.02.2007 um 16:07:17 Uhr
Goto Top
Hallo bastla!

gut, das mit dem find /v hab ich begriffen, aber

ich möchte das auch
hinbekommen wenn ich nicht die ;s
abzähle nach denen die emailadresse
steht. auch wenn das wohl am einfachsten
wäre.

oder habe ich das mit tokens usw nicht gerafft? könnte durchaus der fall sein, aber folgendes müsste doch realisierbar sein:

das müsste dann sowas sein wie,
finde in datei3.txt alle wörter die ein
@ enthalten und schreibe sie in datei4.txt

danke trotzdem leute, ihr habt mir schon bisher sehr geholfen

Gruß Rmp
bastla
bastla 01.02.2007 um 16:15:53 Uhr
Goto Top
Hallo rumpelstielzchen987!

"find" und "findstr" sind grundsätzlich zeilenorientiert.

Wenn Du gesteigerten Wert auf Umwege legst, versuch mit geschachtelten "for /f"-Schleifen die einzelnen Zeilen und darin die einzelnen Wörter abzuhandeln, die "echo"-Ausgabe des Wortes mit "| find ......" zu filtern und bei "errorlevel 0" bzw unter Verwendung von "&&" in eine Datei zu schreiben.

Viel Spaß
bastla
rumpelstielzchen987
rumpelstielzchen987 01.02.2007 um 16:33:31 Uhr
Goto Top
gibt es eventuell eine vbscript variante mit der man alle wörter die @ enthalten in eine neue datei schreiben kann?
edit: oder eines mit dem man nach jedem wort ein Zeilenende fabrizieren kann? Dann kann man ja wieder mit find nach zeilen mit @ suchen.

gruß Rmp
bastla
bastla 01.02.2007 um 16:59:10 Uhr
Goto Top
Hallo rumpelstielzchen987!

Gibt es eventuell einen besonderen Grund für Deine Ablehnung der genau für einen Zweck wie diesen in vermutlich mühsamster Kleinarbeit bei MS entworfenen Funktionalität per for /f "tokens="?

Grüße
bastla
rumpelstielzchen987
rumpelstielzchen987 01.02.2007 um 17:19:29 Uhr
Goto Top
ich habe das noch nie benutzt und keine ahnung wie es funktioniert oder wie man es verwenden muss::rotwerd::


aber mir ist noch ein anderer, sehr umständlicher weg eingefallen:
datei mit editor o.ä. öffnen, alle " " durch "< br >" (ohne leerzeichen, aber sonst wird der beitrag auch dadurch beeinflusst)
ersetzen und dann per batch <body> und </body> vorne und hinten dranhängen. dann die datei als htm speichern öffnen. der user markiert alles und fügt es in eine neue txt ein. nun kann alles schön voneinander getrennt werden.


wenn du lust und zeit hast, mir tokens und co zu erklären, bitte ich darum
danke
gruß rmp


edit:
Ein Token (Art.: „das“; Pl.: „Tokens“) ist ein Stück Text, dem von einer Grammatik eine Bedeutung zugewiesen wird. Dabei ist ein Token die lexikalische Grundeinheit, die ein Parser bearbeitet. Beim Parsen wird jedes Token letztlich mit einem Terminalsymbol der Grammatik verglichen. Wenn das Terminalsymbol zu dem Token passt, kann die entsprechende Regel der Grammatik angewendet werden.

Im einfachsten Fall sind Tokens die Zeichen der ursprünglichen Eingabe: der Buchstabe A erzeugt ein A-Token, usw. Für das Parsen komplexerer Sprachen empfiehlt es sich aber, die Eingabe in einer Zwischenstufe als Kette von komplexeren Token zu betrachten. Dazu fasst ein vorgeschalteter Lexer die Zeichen der Eingabe zu handlichen "Häppchen", eben den komplexeren Token, zusammen. Dabei wird jedem Token ein "Typ" zugewiesen, der dann mit den Terminalsymbolen der Grammatik verglichen werden kann. Zum Beispiel könnte "123" (Folge von mehreren Zeichen) zu dem Token "Zahl:123" (ein einzelnes Token) werden, "foobar" zu "id:foobar" und "begin" zu "keyword:begin".

M$
tokens=X,Y,M-N
Gibt an, welche Tokens aus jeder Zeile bei jeder Iteration an den Rumpf der for-Anweisung übergeben werden. Als Ergebnis davon werden zusätzliche Variablennamen zugewiesen. M-N gibt den Bereich vom M-ten bis zum N-ten Token an. Wenn das letzte Zeichen in der Zeichenfolge tokens= ein Sternchen (*) ist, wird eine weitere Variable zugewiesen, die den übrigen Text der Zeile nach dem zuletzt geparsten Token empfängt.


die eaddys stehen nach dem 10. ",".
also, soweit ich das beurteilen kann:
for /f "tokens=10 {geht 10 überhaupt?} delims=," %%i in ('type "datei3.txt"') do echo %%i > "Adressliste.txt"

edit:
delims ersetzt den standard leerzeichen oder tabulator durch ein zeichen. also müsste ich nichtmal die kommas zählen. ich kanns ja auch als tabulatorversion laden.

also
for /f "tokens=10" %%i in ('type "datei3.txt"') do echo %%i > "Adressliste.txt"
das type raff ich noch nciht... kann das mal bitte jemand erklären?
danke
bastla
bastla 01.02.2007 um 17:50:10 Uhr
Goto Top
Hallo rumpelstielzchen987!

"tokens" sind die Bestandteile (auch eine Bezeichnung als "Felder" wäre durchaus gerechtfertigt) einer (Daten-)Zeile, getrennt durch "delimiter".

Laut Deinem oben dargestellten Satzaufbau, den ich so verstanden habe:
Empfängeradresse;Absenderadresse;Zahlungsbetrag;Verwendungszweck
wäre die Mailadresse des Absenders der 2. Bestandteil Deiner Datenzeile, wobei als Trennzeichen ein ";" verwendet wird - darum die Schreibweise
for /f "tokens=2 delims=;" %i in ('type "Fertig.txt"') do echo %i>> "Adressliste.txt"  
was wiederum nur bedeutet:
Gehe alle Zeilen der Datei "Fertig.txt" (oder bei Dir "Datei3.txt") durch und übernehme in die Variable %i aus jeder Zeile nur den Eintrag nach dem ersten ";" (Token Nr. 2). Schreib schleßlich den Inhalt der Variablen %i in die Datei "Adressliste.txt" (jede Adresse in eine eigene Zeile).

Die enthaltene "type"-Anweisung sorgt für die Ausgabe des Dateiinhaltes, damit die Schleife die einzelnen Zeilen überhaupt erhält. Bei einem einfachen Dateinamen wie "Datei3.txt" wäre es nicht erforderlich - Du könntest auch gleich den Dateinamen ohne Anführungszeichen in die Klammer schreiben, was aber bei Namen mit Leerzeichen zu Problemen führt - daher verwende ich gewohnheitsmäßig die "type"-Schreibweise. Die ' dienen zur Kennzeichnung des dazwischen stehenden Textes als Befehl, der zunächst auszuführen ist und dessen Ausgabe dann an die Schleife übergeben wird - daher könntest Du zB auch an der Kommandozeile ein type "Datei3.txt" eingeben und würdest die Ausgabe dann eben auf den Bildschirm erhalten.

Grüße
bastla

[Edit] Freut mich, dass Du selbst schon das Wesentliche gefunden hast. [/Edit]
[Edit2] Hatte ich da wirklich die ganze Zeit nur ein ">" vor "Adressliste.txt"? Obwohl, den Platz für's Zweite hatte ich ja frei gelassen ... [/Edit2]
bastla
bastla 01.02.2007 um 18:01:29 Uhr
Goto Top
ich kanns ja auch als tabulatorversion laden
Das Problem dabei wäre aber vielleicht, dass dann auch Leerzeichen als Trennzeichen gelten, weshalb ich die Version mit echten Delimitern bevorzuge.

Grüße
bastla
Biber
Biber 01.02.2007 um 18:16:31 Uhr
Goto Top
Moin ihr beiden nochmal,

wikipedia hin, Doktorarbeiten her... ich versuche es mal lieber mit einem banalen Beispiel.

Angenommen, ich hätte mir aus dem Gesülze der wissentschaftlichen Abhandlung oben ein paar Zeilen rauskopiert mit Copy&Paste in eine Datei ForBeispiel.txt, an zwei zufälligen Stellen eine Mailadresse reingestreut und diese Datei bei mir im aktuellen Verzeichnis abgespeichert:

::---datei ForBeispiel.txt
komplexerer Sprachen empfiehlt es sich aber, die Eingabe in einer Zwischenstufe als Kette von komplexeren 
Token zu betrachten. Dazu fasst ein vorgeschalteter Lexer biber@bremen.de die Zeichen der Eingabe zu handlichen 
"Häppchen", eben den komplexeren Token, zusammen. Dabei wird jedem Token ein "Typ" zugewiesen, der dann mit   
den Terminalsymbolen der Grammatik verglichen werden kann. 
Zum Beispiel könnte "123" (Folge von mehreren Zeichen) zu dem Token "Zahl:123"   
(ein einzelnes Token) werden, "foobar" zu "id:foobar" @biber@vi$$$tafanss.vu whatever  

...dann würde folgender unelegant am CMD-Prompt runtergetippselte Befehl das Ergebnis unten bringen:
>for /f "tokens=1-26" %a in ('findstr "@" ForBeispiel.txt') do @for %I in (%a %b %c %d %e %f %g %h %i %k %l %m %n ) do @echo I|find "@"  
biber@bremen.de
@biber@vi$$$tafanss.vu

Übersetzt: in der linken FOR-Anweisung sage ich:
[Bei For-Anweisungen zuerst das in der Klammer lesen und verstehen]
- Nimm alle Zeilen, die Findstr auf der Suche nach dem Zeichen "@" in der Datei ForBeispiel.txt übrig lässt (==findet)...
-diese Zeile fasse als 26 einzelne Tokens (in etwa: Worte) auf ..Token1 wird rechts der For-Anweisung %a heißen, Token2 = %b etc...

- Diese 26 Tokens von %a bis %z also übergebe ich einzeln in der zweiten FOR-Anweisung nacheinander an den Befehl @echo <dasEinzelneToken>|find "@"
- oder übersetzt, jedes "Wort", dass ein "@" enthält, wird "durchgelassen" bzw angezeigt.

Wenn Du also noch ein ">>alleMeineMailAddys.txt" dahinterhängst, dann bist Du halb fertig.
Das sollte in etwa das sein, was bastla oben mit "abzuhandeln, die "echo"-Ausgabe des Wortes mit "| find ......" zu filtern und bei "errorlevel .." gemeint hat.

Gruss Biber

[Sollte nur als Crashkurs zur FOR-Anweisung dienen, nicht als Gesamtlösung]
rumpelstielzchen987
rumpelstielzchen987 01.02.2007 um 18:32:06 Uhr
Goto Top
vielen dank für die antworten jungs.
ich habe mir nach meinen edits bevor ich aktualisiert habe um eure comments zu lesen (xP) die datei inzwischen so zusammengeschraubt:

[code]
@ echo on

set ka=herunterladen.txt

::postfach1
find /i "a@b.de" < %ka% > datei1.txt
find /i "10 EUR" < datei1.txt > datei2.txt
del datei1.txt
find /i "strassenbau" < datei2.txt > datei3.txt
del datei2.txt
for /f "tokens=11 delims=," %%i in ('type "datei3.txt"') do echo %%i > a.txt
del datei3.txt

::postfach2
find /i "b@c.de" < %ka% > datei1.txt
find /i "10 EUR" < datei1.txt > datei2.txt
del datei1.txt
find /i "strassenbau" < datei2.txt > datei3.txt
del datei2.txt
for /f "tokens=11 delims=," %%i in ('type "datei3.txt"') do echo %%i > "b.txt"
del datei3.txt

::postfach3
find /i "d@e" < %ka% > datei1.txt
find /i "10 EUR" < datei1.txt > datei2.txt
del datei1.txt
find /i "strassenbau" < datei2.txt > datei3.txt
del datei2.txt
for /f "tokens=11 delims=," %%i in ('type "datei3.txt"') do echo %%i > "d.txt"
del datei3.txt

::postfach4
find /i "e@f.de" < %ka% > datei1.txt
find /i "10 EUR" < datei1.txt > datei2.txt
del datei1.txt
find /i "strassenbau" < datei2.txt > datei3.txt
del datei2.txt
for /f "tokens=11 delims=," %%i in ('type "datei3.txt"') do echo %%i > "e.txt"
del datei3.txt

::postfach5
find /i "g@h.de" < %ka% > datei1.txt
find /i "10 EUR" < datei1.txt > datei2.txt
del datei1.txt
find /i "strassenbau" < datei2.txt > datei3.txt
del datei2.txt
for /f "tokens=11 delims=," %%i in ('type "datei3.txt"') do echo %%i > "g.txt"
del datei3.txt

::postfach6
find /i "h@i" < %ka% > datei1.txt
find /i "10 EUR" < datei1.txt > datei2.txt
del datei1.txt
find /i "strassenbau" < datei2.txt > datei3.txt
del datei2.txt
for /f "tokens=11 delims=," %%i in ('type "datei3.txt"') do echo %%i > "h.txt"
del datei3.txt

pause
[/code]

eine frage habe ich noch:
macht es einen unterschied, ob ich
for /f "tokens=11 delims=," %%i in ('type "datei3.txt"') do echo %%i > a.txt
, oder
for /f "tokens=11 delims=," %%i in ('type "datei3.txt"') do echo %%i > "a.txt"
schreibe?
ich glaube die " braucht man nur falls der dateiname leerzeichen enthält, aber es wäre gut zu wissen, dass ich unrecht habe^^

jedenfalls vielen dank für eure hilfe
Biber
Biber 01.02.2007 um 18:49:59 Uhr
Goto Top
do echo %%i > "a.txt"
...macht eigentlich keinen Unterschied.

Aber: gewöhne es Dir zumindest bei einem M$-CMD-Interpreter ab, zu viele Leerzeichen zur Erhöhung der Lesbarkeit zwischen "Tokens" (die kennst Du ja jetzt) zu lassen.

Beispiel:
do echo %%i > "a.txt"

--->nach dem %%i, das geECHOt wird, befindet sich ein Leerzeichen, natürlich auch in der Zieldatei
So ist kein Leerziechen am Ende:
do echo %%i> "a.txt"

Kann beim späteren Suchen und Vergleichen durchaus relevant sein.

Außerdem: niemand sollte M$'s Intelligenz und Streben nach Robustheit überschätzen.
Du kannst zwar (am CMD-Prompt) schreiben:
machirgendwas > " dateiname.xyz " [" dateiname.xyz " hat jeweils ein Leerzeichen am Anfang und amm Ende innerhalb der Anführungszeichen]..

...ich weiß aber aus sicherer Quelle, dass einige von M$ mit ausgelieferte Tools in der Tat dann eine Datei mit führendem Leerzeichen anlegen.

Ist ein bisschen mühsam, diese Datei anzusprechen...

Gruß
Biber
bastla
bastla 01.02.2007 um 19:15:10 Uhr
Goto Top
Hallo rumpelstielzchen987!

Da bin ich auch nochmal, weil - die Umleitung in die jeweilige Textdatei mit zB "echo %%i> a.txt" wird Dich nicht froh machen (hatte natürlich ich selbst verbrochen und war mir die ganze Zeit über nicht aufgefallen face-sad ).

Ändere daher bitte diese Umleitung auf die eigentlich gewünschte Schreibweise ">>", um an die vorhandene Datei eine neue Zeile anzufügen und nicht, wie bei ">", jedesmal die Datei neu zu erstellen (mit daher eher dürftigem Inhalt am Ende).

Sorry
bastla
rumpelstielzchen987
rumpelstielzchen987 01.02.2007 um 19:17:48 Uhr
Goto Top
es ging dabei eigentlich um die anführungszeichen bei der dateiangabe ^^.

aber trotzdem danke, war ein guter tipp

Vielen dank an alle Beteiligten, ihr habt mir wirklich enorm geholfen.
grüße rmp
rumpelstielzchen987
rumpelstielzchen987 01.02.2007 um 19:48:38 Uhr
Goto Top
kein problem. vielen dank für den hinweis.

ich gehe jetzt mal davon aus, dass die dateibezeichnung hinter >> nur in anführungszeichen geschriebenwerden muss, falls der dateiname ein leerzeichen enthält.

ihr seid da bisher noch nicht drauf eingegangen
gruß rmp
bastla
bastla 01.02.2007 um 19:53:09 Uhr
Goto Top
... nur in anführungszeichen geschriebenwerden muss, falls der dateiname ein leerzeichen enthält.
Stimmt - wobei es aber in den allermeisten Fällen (eine Ausnahme hat Biber an anderer Stelle beschrieben, finde ich aber jetzt nicht auf die Schnelle) kein Problem ist, die Anführungszeichen trozdem zu verwenden.

Grüße
bastla