fatmike182
Agnotologe
|
Hallo,
folgende Problemstellung: Hab ein .ped-file (kann man mit dem Editor öffnen) welches im Prinzip einen verdammtlangen String enthält (paar hundert mb, sind mehrere Patienten-DNA-Sequenzen, welche jeweils am Anfang eine 5-stellige ZahlenID enthalten). Um das file wirklich weiterbearbeiten zu können muss ich an bestimmten Stellen (nach der ID und während der Sequenz an jeder zweiten Stelle) einen Abstand einfügen (bzw nach der Sequenz = vor der ID einen Zeilenumbruch).
ID & Sequenz kann dadurch unterschieden werden, dass die ID aus Zahlen besteht, die Sequenz aus Buchstaben (na, wer hat gut aufgepasst in der Schule?).
Nun ist es aber so, dass ich nicht _alle_ Daten bearbeiten will, sondern nur bestimmte IDs. Hätt mir das so vorgestellt, dass ich k.A. wieviele input-felder mach in die ich die ID eintrag. beim Enter klicken soll das Script aus dem textfile die Stellen finden an denen die IDs stehen und dann eben bis zum Ende der Sequenz die formatierung durchführen. Diese Strings sollen dann automatisch in ein neues textfile zusammengefasst werden.
Ist das mit Javascript auch möglich? Würde eiegtnlich php nehmen - gute Entscheidung? Kann leider nix grundlegenderes & meine Javakenntnisse sind sehhhhr schlecht.
Kurzes Bsp: Textfile 1: 45362tatagtc....gagct53647tcagt...tagt64788tagc...tacgt67779tgta...cct...
Die Umformatierungsabfrage wäre dann so: Inputfeld1: 45362; Input2: 64788; Input3: 67779 -> submit
die Ausgabe im Textfile dann: 45362 ta ta gt c... ga gc t 64788 ta gc ta cg t 67779 tg ta cc t
tia, Michi
|
Burschi1620
24/7 Santa Claus
|
ich denke hier wäre C empfehlenswerter, imho. Sofern die einzigen Zahlen in dem txt nur die IDs sind gehts gleich noch leichter. IDs einfach eingeben und danach suchen. Wenns gefunden wurde einfach nach jedem zweitem Buchstaben einen Abstand machen und des alles in eine andere txt. Versteh das Problem gerade nicht unbedingt. Was aber allerdings ein Problem sein könnte ist die enorme Länge des Strings  Ich hatte mal ein Programm in C das sowas ähnliches gemacht hat und das hat schon gute 30sek für ein 1mb großes Textfile gebraucht. Darum find ich auch php nicht so die tolle Wahl. edit: Vielleicht wäre reg ex mit perl eine bessere Lösung? (kenn mich da net aus, aber mit reg ex sollte es fits fats gehen)
|
fatmike182
Agnotologe
|
Kann leider nix grundlegenderes & meine Javakenntnisse sind sehhhhr schlecht ... also fällt C usw weg. Kann von mir aus auch mehrere Stunden dauern, solangs nicht manuell gemacht werden muss.
|
that
Hoffnungsloser Optimist
|
Ist das mit Javascript auch möglich? Würde eiegtnlich php nehmen - gute Entscheidung? Kann leider nix grundlegenderes & meine Javakenntnisse sind sehhhhr schlecht. In JS gehts, wenn du einen Host verwendest, der File I/O kann, z.B. den Windows Scripting Host, der bei Windows dabei ist (cscript bzw. wscript), mit seinem FileSystemObject. Gegen PHP spricht nichts, wenn du es am besten kannst. Was brauchst du: Array erwünschter IDs einlesen - geht File I/O zeichenweise - geht Zeichen erkennen ob Buchstabe oder Ziffer - trivial Strings zusammenhängen - um die IDs zu bauen oder die Zweiergruppen - trivial Mitzählen und nach jedem 2. Zeichen auf 0 stellen und ein Space ausgeben - trivial Wenn eine ID erkannt ist, im Array nachschauen ob erwünscht - geht auch
|
fatmike182
Agnotologe
|
ok - file I/O muss ich mir noch anschaun, aber wird ähnlich sein wie ein Datenbankzugriff nehm ich an.
Na dann bin ich mal gespannt, hab schon ewig nix mehr gemacht. Thx!
|
Burschi1620
24/7 Santa Claus
|
|
gue
Addicted
|
Solangs vom Speicher her geht kannst dudas Aufsplitten (auch) ca. so machen: $arr = preg_split("/([0-9]+)/", $str, -1, PREG_SPLIT_DELIM_CAPTURE);
foreach ($arr as $v) {
echo $v . "\n";
}
Statt echo natürlich in die Datei schreiben und so und das Einfügen der Leerzeichen in die DNA Sequenz sollte auch kein Problem sein.
|
fatmike182
Agnotologe
|
Hallo,
hab jetzt mehr Infos erhalten und das File. Da ist mir gleich aufgefallen: nicht 500mb oder so, sodern 3GB ist das Textfile groß!
Später kann ich die Formatierungsschritte ja dann auf verschiedenen Rechnern ausführen lassen und davor die Dateigröße auf <1GB runterbrechen, aber leider muss ich das File zunächst mal nach der ID sortieren.
Wie mach ich das am gscheitesten? (hab bis dato viel mit Datenbanken gearbeitet, aber nie mit so dermaßen großen Datenengen) Mit dem bufferflow (cache) arbeiten stell ich mir da irgendwie utopisch vor... Soll ichs in eine Datenbank aufsplitten (Spalten ID und eben Sequenz) - ob sich das mit der max Zeichenanzahl ausgeht ist fraglich: 600.000 Zeichen mit Spaces usw aber ca 1Mio Zeichen. Auf einzelne Textdatein aufsplitten lassen (werden dann eben 2000 stk ca sein) welche den Namen der id haben und die dann geordnet zusammenführen?
Vorteil an den einzelnen Textdatein wäre, dass ich die dann auch einzeln einspeisen könnte und man evtl nebenbei am PC arbeiten könnte.
Was ist generell besser in dem Fall: eine foreach-schleife (thx @gue) oder mit while?
TIA, Michi
|
COLOSSUS
AdministratorGNUltra
|
E:\ Tag schon zu lang, hab die Frage falsch aufgefasst.  Es ist 100%ig sicher, dass Die IDs nur numerisch, und auch dass die Datensaetze nur alphabetisch sind? Dann ist es in C trivial, das File entsprechend in ein durch \n separiertes File umzuwursten, und dann mit geeigneteren Tools weiterzubearbeiten. Kannst du mal das erste Megabyte oder so des Files uploaden als Testmatieral?
|
Römi
Hausmeister
|
Meine Gedanken dazu: Ich hab zuerst an eine lösung per regex gedacht, aber bei 3GB ist das wohl nicht machbar. Ich glaub am sinnvollsten wäre es mit Filestreams zu arbeiten, du kannst ja auch schrittweise so eine Datei einlesen und musst sie nicht als ganzes laden. Stell mir das so vor dass du die Datei durchgehst bis du die interessanten stellen findest (ID's?) und damit dann weiterarbeitest. Sollte ohne weiteres mit php gehn, schätze da gibts auch schon beispiele im internet. Aber ich bin sicher nicht der qualifizierteste um dir da zu helfen
|
that
Hoffnungsloser Optimist
|
Was ist generell besser in dem Fall: eine foreach-schleife (thx @gue) oder mit while? Zeichenweise oder blockweise direkt aus der Datei einlesen (mit fread, AFAIK gibts das auch in PHP) und gleich wieder in die Zieldatei schreiben (fwrite). Dann brauchst du kaum Speicher, egal wie groß die Datei ist.
|
gue
Addicted
|
Also ich würde es nicht in eine Form bringen, in der die ID am Anfang ist und DANN sortieren (z.B. mit dem sort tool), ich glaube nicht, dass das bei einer so großen Datenmenge funktioniert. Ich würde es so machen: Die Daten wie bereits erwähnt mit fread (und gegebenenfalls, also wenn ein numerischer Wert am Ende des Einlesepuffers ist, mit fseek) durchforsten und eine Map anlegen, in der ID und entsprechender Offset in der Datei gespeichert wird (in PHP ist eine Map einfach ein assoziatives Array), wobei die ID der Schlüssel und der Offset der Wert ist. Diese Map sortierst du dann (falls das in PHP nötig ist) und iterierst über die sortierten Schlüssel. Zu jedem Wert fseekst du hin, liest die Zeichenfolge aus (bis zum nächsten numerischen Wert) und schreibst sie samt Schlüssel in deine Ausgabedatei. Das Vorgehen ist übrigens für die meisten Programmiersprachen gleich, in dem Fall würde ich mich vielleicht auf etwas performanteres als PHP einlassen (beispielsweise Java) aber wenn PHP das einzige ist, was du kannst, kannst du es natürlich auch damit versuchen.
|
fatmike182
Agnotologe
|
von Java weiß ich nix mehr (hab letztes Jahr paar Sachen damit gemacht, eigentlich eh ähnliches und auch mit Buffer-streams) - leider.
das mit der Map hoffe ich verstanden zu haben, schaus mir an! Thx. Aber was wär dabei, wenn ich die große txt in ca 2000 "kleine" splitte ind die einzeln bearbeite und dann zusammenführe?
|
gue
Addicted
|
Stimmt, das ist eigentlich noch einfacher (braucht halt auch doppelt so lange aber dafür hast du's wahrscheinlich doppelt so schnell implementiert).  Nur so wie es COLOSSUS vorgeschlagen hat, würde ich es nicht machen.
|
fatmike182
Agnotologe
|
vorteil wäre dann, dass ich wirklich ohne Aufwand mehrere Rechner daran arbeiten lassen kann.
File hab ich zzt nicht bei der Hand, werd heute evtl mitn Programmieren anfangen, kann euch ein Sample zeigen dann (werds eh die Sequenzen deutlich kürzen)
Was dann noch dazu kommen würde wäre, dass ich ein Keyfile (in dem Geschlecht, Alter usw gespeichert sind; jede ID vom großen file hat einen Eintrag im Keyfile) einspeisen muss (zwischen ID und Sequenz). Werde also evtl das große File so splitten, dass ich Pro ID+Sequenz zwei Datein hab zB: 5624 tg tt gt aa ... -> 5624.txt (Inhalt: 5624) -> 5624dna.txt (Inhalt: tg tt gt aa) Keyfile wird dann auch gesplittet (Keyfile original: 5624 m 23 ..) -> 5624key.txt (Inhalt: m 23 ...) und alle drei in der Reihenfolge $ID.txt + $IDkey.txt + $IDdna.txt zusammengeführt. Na bin schon gespannt. Ist das ein großer Pfusch? Btw. ist es den Rechenaufwand wert, wenn ich Id und Sequenz splitte - ich mein, früher oder später muss ichs so oder so machen - aber nur als Stringzerlegung, icht als Filegemetzel.
|