Search & Replace Tool gesucht

ikosaeder

Teekannen-Agnostiker
Default ist der lokale Pfad /s nimmt auch die Unterverzeichnisse mit. Mit /p kannst du den Pfad spezifizieren. Ich kann es nicht ausprobieren, da ich hier nur Linux habe.
Teste bitte erst an einzelnen Dateien und mach evt ein Backup, damit du dir nicht alles zerschiesst, wenn etwas schiefgeht.
Außerdem wird das trotzdem einige Zeit dauern. Ein Test mit 400000 Zeilen = 26 MB, davon die Hälfte mit CW dauert bei mir etwa 700 Sekunden. 200000 Zeilen dauert 159 Sekunden. Es skaliert also nicht linear (warum auch immer).
Also 1000 Dateien könnte schon einige Stunden dauern.
 

Bratkartoffel

gebratene Kartoffel
Premium-User
Hi,

wie wäre es mit dem sed? Den gibts auch für Windows (Mit cygwin oder standalone mit GnuWin32).

Code:
sed --in-place=.old -e '/CW/d' *.txt

Sollte vom Speicherverbrauch und Performance so ziemlich der schnellste sein.

Grüsse,
BK
 

ikosaeder

Teekannen-Agnostiker
Ich habe das mal mit C++ zum Vergleich gemacht, weil mich die lange Laufzeit des Pythonscripts stutzig machte. und siehe da, c++ braucht nur wenige Sekunden um die Dateien zu bearbeiten. Selbst 600 MB mit 10 Mio Zeilen brauchen nur 10 Sekunden.
C++:
#include <iostream>
#include <fstream>
#include <string>
using namespace std;

int main () {
  size_t returnval;
  string line;
  string teststring;
  teststring="CW";
  ifstream inFile;
  ofstream outFile;
  inFile.open("Removeline.test");
  outFile.open("tempfile.txt");
  if (inFile.is_open())
  {
  while ( getline(inFile,line ))
  {
  returnval=line.find(teststring);
  if(returnval!=std::string::npos){
  }
  else{
  outFile << line << '\n';
  }
  }
  inFile.close();
  outFile.close();
  }
  ifstream source("tempfile.txt", ios::binary);
  ofstream dest("Removeline.test", ios::binary);

  dest << source.rdbuf();

  source.close();
  dest.close();
}

Ich bin nicht so fit in C++, wahrscheinlich geht es noch besser, aber das Programm erfüllt seinen Zweck. Mich interessiert nur, warum Python so schlecht abschneidet. Faktor 10 hätte ich ja akzeptiert.

Im Übrigen ist C++ auch schneller als sed
time ./CRemoveLines

real 0m10.787s
user 0m7.858s
sys 0m2.604s

time sed --in-place=.old -e '/CW/d' Removeline.test
real 0m28.521s
user 0m14.836s
sys 0m13.514s
 

Torsten Ernst

Mitglied
So, nun habe ich über 2 Stunden alles ausprobiert und nichts hat wirklich funktioniert. Keine Ahnung was ich falsch mache. Das Pythonscript bekomme ich nicht zum Laufen, da im DOS-Prompt immer folgende Meldung zurück gegeben wird:

Fehler: Argument/Option ungültig - 'removeCwLines.py'.
Geben sie "Forfiles /?" ein, um die Syntax anzuzeigen.

Das habe ich gemacht und alles Mögliche probiert, ohne Erfolg. Egal was ich versuche, es kommt immer Fehler: Argument/Option... ungültig zurück.

sed habe ich auch ausprobiert, da erhalte ich folgende Meldung:

sed: -e Ausdruck #1, Zeichen 1: Unbekannter Befehl: " ' "

MfG, Torsten
 

Alice

Erfahrenes Mitglied
Hallo,

ich habe ca. 1000 Textdateien. In diesen müssen Zeilen gelöscht werden wo ein definierbares Wort vorkommt. Nun suche ich dafür ein Tool, welches dateiübergreifend nach bestimmten Text sucht und dann die komplette Zeile (in der ein Treffer vorliegt) löscht. Eine normale "Suchen & Ersetzen" Funktion reicht hier nicht aus, da ich nicht alle 1000 Dateien einzeln öffnen möchte. ;-) Das Tool darf auch Geld kosten, wichtig ist das es funktioniert. Mit Notepad++ habe ich es bereits versucht, dass klappt aber nicht. Wer weiß Rat? Vielen Dank vorab.

Mit freundlichen Grüßen, Torsten

Also ich habe so etwas schon ein paar mal mit SVG-Dateien gemacht (~ 3000 Stück) und habe dazu Notepad++ verwendet.

Füge deine Dateien in ein Ordner ein wie z.B. "Meine Dateien" und öffne Notepad++. Klick oben auf Suchen und dann auf Ersetzen... Es öffnet sich eine Maske. Dort gehst Du auf den Reiter "In Dateien suchen" und ziehst dein ding durch.
 

ikosaeder

Teekannen-Agnostiker
Also ich habe das Pythonscript nochmal verbessert. Es scheint als wäre remove das Problem. Lässt sich zwar sehr elegant schreiben aber ist ineffizient.
Code:
#!/usr/bin/python
import os,sys,re,time,string
start = time.clock()
b=[]
try:
  filename=sys.argv[1]
  f = open( filename, 'rU')
  a = f.readlines()
  f.close()
except OSError, e:
  print "Input file could not be opened",e
elapsed = (time.clock() - start)
print "File gelesen" + str(elapsed)
for i in a:
  s=i.find('CW')
  if(s==-1):
  b.append(i)
elapsed = (time.clock() - start)
print "Zeilen bearbeitet" + str(elapsed)
try:
  f=open(filename,'wB')
  f.write("".join(b))
  f.close
except OSError, e:
  print "Output file could not be opened",e
elapsed = (time.clock() - start)
print "File geschrieben" + str(elapsed)
print elapsed

Damit kann auch Python 10 Mio Zeilen in sinnvoller Zeit bearbeiten. Es ist zwar am langsamsten
time python2.7 RemoveLine.py Removeline.test

real 0m41.161s
user 0m25.568s
sys 0m3.681s
Aber es ist nur noch um einen Faktor 4 langsamer als C++. Mit der zusätzlichen Flexibilität würde ich also auf Python setzen.
NP++ kann eine Datei mit 10 Mio Zeilen übrigens nicht öffnen.
 
Zuletzt bearbeitet:

Torsten Ernst

Mitglied
Ihr seid hier alle wirklich sehr hilfsbereit, großes Lob in die Runde und nochmals Danke dafür! :)
Ich werde heute Abend einen zweiten Anlauf nehmen, ich hoffe diesmal klappt es. Mit NP++ hatte ich das bereits getestet, dass fünktioniert nur bei kleinen Dateien gut. Bei Dateien um die 20MB habe ich nach 10 min abgebrochen weil sich nichts tat.

MfG, Torsten
 

Torsten Ernst

Mitglied
Leider hat es wieder nicht funktioniert, ich bekomme wieder die Fehlermeldung "Argument/Option ungültig". Forfiles selbst funktioniert auf dem Rechner, so konnte ich z.B. mit forfiles /p "g:\rbn-daten\2012\2" /m "*.csv" alle Dateien im Ordner auslesen. Ich denke die Befehlszeile ist nicht korrekt, zumindestens unter Windows. Die Datei removeCwLines.py liegt im Ordner "2", also zusammen mit den CSV-Dateien. Oder muss noch etwas auf dem Rechner installiert werden, damit er mit Python etwas anfangen kann?

MfG, Torsten