String in mehreren Dateien durch anderen String ersetzen? Topic is solved

Stelle Fragen zur Programmierung mit Autohotkey

Moderator: jNizM

Lightgreen38
Posts: 6
Joined: 24 Dec 2018, 08:45

String in mehreren Dateien durch anderen String ersetzen?

18 Mar 2019, 12:21

Liebes AHK-Forum,

ich habe ein Script geschrieben, das einen String in sogenannten SDLXLIFF-Dateien (.sdlxliff) durch einen anderen String ersetzen soll. Das Ersetzen an sich funktioniert auch, nur wenn ich das in mehreren Dateien, die sich in verschiedenen Unterordnern befinden, machen möchte, klappt es irgendwie nicht. Ist vermutlich irgendein kleiner, dummer Fehler, aber die "Übergabe" zwischen dem Loopen der Dateien und dem Parsen klappt nicht. Was mache ich falsch?

Hier der Code (mit Ordnerstruktur-Beispiel, wobei sich die Ordnernamen ändern können, z.B. statt "en-GB" kann es beim nächsten Mal "ru-RU" sein)

Code: Select all

#SingleInstance, Force

; Ordnerstruktur (Beispiel):
; c:\studio\
; c:\studio\de-DE
; c:\studio\de-DE\test.sdlxliff
; c:\studio\en-GB
; c:\studio\en-GB\test.sdlxliff
; c:\studio\fr-FR
; c:\studio\fr-FR\test.sdlxliff
; c:\studio\tm

Loop, Files, c:\studio\*.sdlxliff, R	; R=recurse into subfolders

filelist := A_LoopFileFullPath

loop, Parse, filelist, `|
{
	; The above parses the list based on the | character
	fileread, EmptySegs, %filelist% ; Read the file
	fileDelete, %filelist%         ; Delete the file
	EmptySegs := RegExReplace(EmptySegs, " conf=""([a-zA-Z]+)""", "")
	fileAppend, %EmptySegs%, %filelist% ; Re-create the file with new contents
}

Return
Bin für jede Hilfestellung dankbar!
Ahk_fan
Posts: 50
Joined: 31 Aug 2018, 14:34

Re: String in mehreren Dateien durch anderen String ersetzen?  Topic is solved

18 Mar 2019, 15:10

hmm, eine Loop reicht doch, oder ?

Code: Select all

#SingleInstance, Force

; Ordnerstruktur (Beispiel):
; c:\studio\
; c:\studio\de-DE
; c:\studio\de-DE\test.sdlxliff
; c:\studio\en-GB
; c:\studio\en-GB\test.sdlxliff
; c:\studio\fr-FR
; c:\studio\fr-FR\test.sdlxliff
; c:\studio\tm

Loop, Files, c:\studio\*.sdlxliff, R	; R=recurse into subfolders
{
		fileread, EmptySegs, %A_LoopFileFullPath% ; Read the file
		fileDelete, %A_LoopFileFullPath%         ; Delete the file
		EmptySegs := RegExReplace(EmptySegs, " conf=""([a-zA-Z]+)""", "")
		fileAppend, %EmptySegs%, %A_LoopFileFullPath% ; Re-create the file with new contents
}
Return
regards,
AHK_fan :)
Lightgreen38
Posts: 6
Joined: 24 Dec 2018, 08:45

Re: String in mehreren Dateien durch anderen String ersetzen?

18 Mar 2019, 17:48

Ah, super, das war tatsächlich der Fehler :)
(Obwohl ich glaube ich dann noch nicht richtig den Unterschied zwischen Loop, Files und Loop, Parse begriffen habe...)
Danke!
just me
Posts: 6379
Joined: 02 Oct 2013, 08:51
Location: Germany

Re: String in mehreren Dateien durch anderen String ersetzen?

19 Mar 2019, 03:41

Lightgreen38 wrote:... (Obwohl ich glaube ich dann noch nicht richtig den Unterschied zwischen Loop, Files und Loop, Parse begriffen habe...) ...


Moin,

Deine Erste Schleife

Code: Select all

Loop, Files, c:\studio\*.sdlxliff, R	; R=recurse into subfolders
	filelist := A_LoopFileFullPath
überschreibt bei jedem Durchlauf den Inhalt der Variablen filelist mit dem aktuellen Inhalt der Variablen A_LoopFileFullPath. Nach Ende der Schleife enthält filelist deshalb genau einen Dateipfad, den der letzten gefundenen Datei. Den Listentrenner | benutzt Du überhaupt nicht.

Deine zweite Schleife

Code: Select all

loop, Parse, filelist, `|
{
	; The above parses the list based on the | character
	fileread, EmptySegs, %filelist% ; Read the file
	...
versucht nun, den Inhalt der Variablen filelist mit Hilfe des Trennzeichen | aufzutrennen. Die einzelnen Teile werden dabei in die Variable A_LoopField gestellt. Die wird dann normalerweise innerhalb der Schleife weiter verarbeitet.
In Deinem Skript enthält die Variable filelist kein Trennzeichen und damit auch keine Liste von Dateien. Deshalb wird der Variablen A_LoopField bereits im ersten Durchlauf der komplette Inhalt der Variablen filelist zugewiesen. Damit ist das auch schon der letzte Durchlauf.
Du verarbeitest nun aber nicht die Variable A_LoopField sondern die Variable filelist. Das klappt nur, weil die Variable nur exakt einen kompletten Dateipfad enthält.

Lange Rede, kurzer Sinn: Dein Zweischleifenkonstrukt (, das Du nicht brauchst,) würde wie folgt funktionieren:

Code: Select all

FileList := ""
Loop, Files, c:\studio\*.sdlxliff, R	; R=recurse into subfolders
	FileList .= A_LoopFileFullPath . "|" ; kompletten Pfad der aktuell gefundenen Datei und ein Trennzeichen an FileList anhängen
FileList := RTrim(FileList , "|") ; letztes TRennzeichen am Ende entfernen

loop, Parse, filelist, `|
{
	; The above parses the list based on the | character
	FileRead, EmptySegs, %A_LoopField% ; Read the file ; <<<< der aktuelle Dateipfad steht in A_LoopField
	FileDelete, %A_LoopField%         ; Delete the file
	EmptySegs := RegExReplace(EmptySegs, " conf=""([a-zA-Z]+)""", "")
	FileAppend, %EmptySegs%, %A_LoopField% ; Re-create the file with new contents
}
Return

Für die Verarbeitung der einzelnen Dateien hätte ich einen anderen Vorschlag, das File-Objekt. Damit kann man Dateien auch überschreiben:

Code: Select all

Loop, Files, c:\studio\*.sdlxliff, R	; R=recurse into subfolders
{
	If (SdlXliff := FileOpen(A_LoopFileFullPath, "rw")) { ; Versuch, die Datei zum Überschreiben zu öffnen
		StartPos := SdlXliff.Pos ; Startposition merken, falls die Datei eine BOM hat
		EmptySegs := SdlXliff.Read() ; Datei komplett einlesen
		EmptySegs := RegExReplace(EmptySegs, " conf=""([a-zA-Z]+)""", "", Counter) ; Text ersetzen und Ersetzer zählen
		If (Counter) { ; falls Text ersetzt wurde
			SdlXliff.Pos := StartPos ; Datei wieder auf Start setzen
			SdlXliff.Write(EmptySegs) ; geänderten Text zurückschreiben
			SdlXliff.Length := Handle.Pos ; Dateiende auf aktuelle Größe setzen
		}
		SdlXliff.Close() ; Datei schließen
	}
	Else
		MsgBox, 16, Fehler!, Die Datei %A_LoopField% konnte nicht geöffnet werden!
}
Ich habe den Code aber nicht selbst getestet.
Lightgreen38
Posts: 6
Joined: 24 Dec 2018, 08:45

Re: String in mehreren Dateien durch anderen String ersetzen?

21 Mar 2019, 13:51

Danke Dir für die ausführliche Erklärung!

Dann wird mir auch der Unterschied klar zwischen selbst definierten Variablen und Spezialvariablen wie A_LoopFileFullPath. Ich war avon ausgegangen, dass die Variable filelist hier mit allen Inhalten des Loops befüllt wird, nicht nur mit dem letzten. Wohingegen bei A_LoopFileFullPath alle Inhalte "durchgerattetert" werden -- und das offensichtlich ohne Trenner, weil bei MsgBox jeder Inhalt nacheinander angezeigt wird.

Return to “Ich brauche Hilfe”

Who is online

Users browsing this forum: No registered users and 16 guests