64142
Goto Top

Massendaten Text editor

besser einen dos befehl verwenden, denke ich mir ..

Hallo zusammen,

habe das forum durchsucht, aber noch keinen passenden Hinweis zur Lösung meines Problemes gefunden.

mir liegen ca 15000 xml files vor in denen ein bestimmter string geändert werden sollte.
kann jetzt mit einigen Texteditoren mal 500 dateien öffen, string suchen und ersetzen und wieder abspeichern, für alle Dateien dauert aber auch das eine kleine Ewigkeit.

Da müsste es soch ein Tool oder einen cmd befehl dafür geben, der das schneller löst?
zumal es für mich wohl keine einmalige Aktion bleibt, sondern das öfter vorkommen wird.

Die xml dateien sind ca 40 kB groß und mit jedem beliebigen Editor bisher zu lesen gewesen,
es liegen alle in einem Ordner,
Betriebssystem ist Windows XP - tja, das Unix dort mehr kann, ist mir auch bekannt, aber das hilft mir hier leider auch nicht weiter face-smile

Danke für jeden Beitrag zur Lösung.

Gruß
halfprice

Content-Key: 85586

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

Printed on: April 16, 2024 at 10:04 o'clock

Member: geTuemII
geTuemII Apr 15, 2008 at 16:13:07 (UTC)
Goto Top
Hallo halfprice,

erstmal willkommen hier im Forum. face-smile

Sag doch mal, was den auszutauschenden Text auszeichnet (Position in der Datei, Wortlaut...) und wogegen er ausgetauscht werden soll.

geTuemII
Member: SarekHL
SarekHL Apr 15, 2008 at 16:14:12 (UTC)
Goto Top
Der HTML-Editor Phase 5 beherrscht beispielsweise die Funktion "Dateiübergreifendes Suchen und Ersetzen" ...
Member: miniversum
miniversum Apr 15, 2008 at 16:35:28 (UTC)
Goto Top
Ich kann mich nur anschliesen. Poste doch mal den relevanten Teil der Datei und wie es danach aussehen soll.

Der Editor PSPad kann da glaube ich auch mehr Dateien. Dort gibt es auch die Funktion einen ganzen Ordner zu durchsuchen und in allen Dateien (oder durch Benutzung eines Filters nur bestimmten) darin Wörter zu suchen und zu ersetzen.
Member: bastla
bastla Apr 15, 2008 at 17:11:04 (UTC)
Goto Top
Hallo halfprice!

Für eine automatisierte Lösung wären einige weitere Details wichtig, zB:

- Befinden sich die Dateien alle im selben Ordner, und sollen sie dort bleiben?
- Sollen die alten Dateien überschrieben werden, oder brauchst Du Sicherungskopien?
- Sind alter und neuer String jeweils konstant, und woher sollen die Werte dafür kommen?

Grüße
bastla
Mitglied: 64142
64142 Apr 16, 2008 at 11:10:02 (UTC)
Goto Top
- alle Dateien im gleichen Ordner, sollen auch gerne dort bleiben
(wenn nötig können sie auch kopiert werden)
- sicherungskopie brauche ich keine
- sting in den 15000 ist nicht überall drin, sondern kann abweichen.

möglichens szenario:

in 5000 von den 15000 files steht "ich hab dich lieb" in allen anderen "ich hab dich nicht lieb"
die 5000 sollen geöffnet werden diesen "ich hab dich lieb" durch "ich hab dich nicht lieb" ersetzen und einfach wieder speichern.


allerdings suche ich ja ein tool, das auch mal einen gleichen string in 15000 oder sogar 50000 dateien ersetzen könnte (10000 wären schon mal ein guter anfang face-smile )
Member: bastla
bastla Apr 16, 2008 at 12:14:42 (UTC)
Goto Top
Hallo halfprice!

Es gibt natürlich, abgesehen von den genannten Editoren, eine Menge an spezialisierten "Search & Replace"-Tools verschiedenster Art und Lizenz - wenn's mit Bordmitteln bzw als Eigenbau gehen soll, dann etwa so:
'SRF.vbs  
Const Ordner = "Z:\Testdaten"  
Const ToReplace = "ich hab dich nicht lieb"  
Const ReplaceBy = "ich hab dich lieb"  

Set fso = CreateObject("Scripting.FileSystemObject")  
For Each File In fso.GetFolder(Ordner).Files
	WScript.Echo "Bearbeite: " & File.Name  
	Text = fso.OpenTextFile(File).ReadAll
	fso.CreateTextFile(File, True).Write Replace(Text, ToReplace, ReplaceBy)
Next
WScript.Echo "Fertig"  
Dieses VBScript solltest Du unter Verwendung eines beliebigen Texteditors zB unter "C:\Scripts\SRF.vbs" speichern (falls Du den Windows-Editor verwendest, bitte darauf achten, beim Speichern den Dateinamen unter Anführungszeichen zu setzen, da ansonsten ".txt" angefügt wird) und von der Kommandozeile ("Start / Ausführen / CMD") so starten:
cscript //nologo "C:\Scripts\SRF.vbs" 
Auf diese Art siehst Du immer, welche Datei gerade bearbeitet wird. Falls Du diese optische Kontrolle nicht benötigst, entferne einfach die Zeile "WScript.Echo "Bearbeite: " & File.Name" - dann kannst Du das Script auch einfach per Doppelklick ausführen.

In dieser Version wird beim Suchen zwischen Klein- und Großschreibung unterschieden (lässt sich bei Bedarf ändern).

Achtung: Es werden (ohne Sicherung) alle Dateien des angegebenen Ordners überschrieben (auch wenn keine Ersetzung nötig war - dann eben mit dem Originalinhalt) - bitte mit Kopien testen!

Eine Variante, bei der nur veränderte Dateien neu geschrieben werden, kann ich bei Bedarf auch anbieten - die Laufzeit des Scripts würde sich dadurch verlängern, ob allerdings wesentlich, kann ich nicht abschätzen (wäre ggf zu testen).

Grüße
bastla

P.S.: Ich habe mir erlaubt, die Beispielstexte für die Ersetzung etwas zu variieren ... face-wink
Mitglied: 64142
64142 Apr 16, 2008 at 15:28:16 (UTC)
Goto Top
Perfekt, das ist genau das, was ich im grunde gesucht habe.
ohne viel schnick/schnack und rasend schnell.

vielen dank.

mir ist allerdings kein unterschied aufgefallen, ob ich es (ohne dem löschen der file.name zeile)per doppelklick, oder aus einer schell heraus öffne (außer natürlich, dass die shell am ende zugeht).

interessant wäre ein log file, das mitgeschrieben wird (im gleichen ordner) in dem einfach die dateinamen geschrieben werden, die neu sind, aber das ist wohl wie in deinem nachsatz, mit performance einbußen verbunden.

DANK dem BASTLA face-smile
Member: bastla
bastla Apr 16, 2008 at 15:50:41 (UTC)
Goto Top
Hallo halfprice!

... mit performance einbußen verbunden.
Kannst ja mal testen, ob es eine signifikante Änderung der Laufzeit gibt:
'SRFL.vbs  
Const Ordner = "Z:\Testdaten"  
Const LogFile = "Z:\SRF-Log.txt"  
Const ToReplace = "ich hab dich nicht lieb"  
Const ReplaceBy = "ich hab dich lieb"  

Set fso = CreateObject("Scripting.FileSystemObject")  
Set LogF = fso.CreateTextFile(LogFile, True)
For Each File In fso.GetFolder(Ordner).Files
	Text = fso.OpenTextFile(File).ReadAll
	If InStr(Text, ToReplace) Then
		fso.CreateTextFile(File, True).Write Replace(Text, ToReplace, ReplaceBy)
		LogF.WriteLine File.Name
	End If
Next
WScript.Echo "Fertig"  

Grüße
bastla
Mitglied: 64142
64142 Apr 17, 2008 at 13:28:34 (UTC)
Goto Top
supi - die performance ist nicht wirklich anders.

wie es der teufel will - ich dachte, das brauche ich nicht - muß ich einen string ändern, der in dem xml file über zwei zeilen gehen muß (da ich nicht einen string ändern muß, sondern einen nicht forhandenen einfügen - siehe beispiel)

manchmal steht dort drin folgendes für ein attribute - es gibt bis zu 20:

<gs:Attribute>
<gs:Name>ITEM NAME</gs:Name>
<gs:Value></gs:Value>
</gs:Attribute>

und das attribute soll neu gesetzt werden.
wenn ich dort suchen erstetzen, wie in dem vbs script mache, muß ich einen zeilenumbruch einfügen.

ergebnis sollte sein:

<gs:Attribute>
<gs:Name>ITEM NAME</gs:Name>
<gs:Value>12345</gs:Value>
</gs:Attribute>


vielleicht kann man dort auch einen anderen weg gehen, aber das suchen ersetzen scheint mir ganz brauchbar, brauche nun nur für die zwei strings ein zeichen für zeilenumbruch, oder denke ich falsch?

dachte an sowas, wie:

Const ToReplace = "<gs:Name>ITEM NAME</gs:Name>
<gs:Value></gs:Value>"
Const ReplaceBy = "<gs:Name>ITEM NAME</gs:Name>
<gs:Value>12345</gs:Value>"
Member: miniversum
miniversum Apr 17, 2008 at 16:10:01 (UTC)
Goto Top
Versuchs mdamit:
Const ToReplace = "<gs:Name>ITEM NAME</gs:Name>" & vbCrLf & "<gs:Value></gs:Value>"
Const ReplaceBy = "<gs:Name>ITEM NAME</gs:Name>" & vbCrLf & "<gs:Value>12345</gs:Value>"
Member: bastla
bastla Apr 17, 2008 at 16:55:11 (UTC)
Goto Top
... lasse aber das "Const" jeweils weg.

Grüße
bastla
Mitglied: 64142
64142 Apr 18, 2008 at 06:22:32 (UTC)
Goto Top
hm,

tut leider nicht.
er sagt jetzt zwar, dass er die alle bearbeitet, die datei wird auch neu geschrieben (neues datum), aber der inhalt bleibt gleich
so sieht nun mein skript aus - ist da noch was falsch?


'SRF.vbs
Const Ordner = "C:\data"
ToReplace = "<gs:Name>ITEM NAME</gs:Name>" & vbCrLf & "<gs:Value></gs:Value>"
ReplaceBy = "<gs:Name>ITEM NAME</gs:Name>" & vbCrLf & "<gs:Value>12345</gs:Value>"

Set fso = CreateObject("Scripting.FileSystemObject")
For Each File In fso.GetFolder(Ordner).Files
WScript.Echo "Bearbeite: " & File.Name
Text = fso.OpenTextFile(File).ReadAll
fso.CreateTextFile(File, True).Write Replace(Text, ToReplace, ReplaceBy)
Next
WScript.Echo "Fertig"
Member: bastla
bastla Apr 18, 2008 at 10:06:49 (UTC)
Goto Top
Hallo halfprice!

Die Ersetzung erfolgt "case sensitive" - um das zu ändern, bitte die folgende Zeile durch das Hinzufügen von ", 1, -1, vbTextCompare " ändern auf:
fso.CreateTextFile(File, True).Write Replace(Text, ToReplace, ReplaceBy, 1, -1, vbTextCompare )
Je nach Datenherkunft könnte das Zeilenende anstelle von vbCrLF vielleicht nur ein vbCr oder ein vbLF sein.

Schließlich solltest Du die Zeilen noch genau daraufhin untersuchen, ob etwa Leerzeichen oder ein TAB (nicht nur am Zeilenende) enthalten sind - diese müssten natürlich auch im Suchmuster ("ToReplace") entsprechend berücksichtigt werden.

Grüße
bastla

P.S.: Wenn ich die von Dir angegebenen Beispielzeilen verwende, funktioniert's auch schon mit Deinem zuletzt geposteten Script ...

P.P.S.: Bitte setze beim Posten von Scripts oder anderen Inhalten, die möglichst unverändert dargestellt werden sollen, die Tags < code> bzw < /code> (natürlich ohne Leerzeichen).
Mitglied: 64142
64142 Apr 18, 2008 at 11:20:46 (UTC)
Goto Top
Funktioniert - vielen dank nochmal für die Mühen und die Geduld face-smile