Seite 2 von 2
Re: Zeilen txt löschen
Verfasst: 30.08.2017 22:05
von Fanpost
@GPI
Die Zeilen in der TXT sehen z.B. wie folgt aus und es sind max 189 Zeilen vorhanden:
<g1#1#1#1#00001.bmp><t280#460#120#arial#NI233><t280#620#120#arial#SW: 01.02.00><t280#760#160B#arial#Serien - Nr: 00001>
<g1#1#1#1#00002.bmp><t280#460#120#arial#NI233><t280#620#120#arial#SW: 01.02.00><t280#760#160B#arial#Serien - Nr: 00002>
<g1#1#1#1#00003.bmp><t280#460#120#arial#NI233><t280#620#120#arial#SW: 01.02.00><t280#760#160B#arial#Serien - Nr: 00003>
.
<g1#1#1#1#00189.bmp><t280#460#120#arial#NI233><t280#620#120#arial#SW: 01.02.00><t280#760#160B#arial#Serien - Nr: 00189>
Es handelt sich um Steuerzeichen inkl. Text für ein Druckprogramm. Sollten z.B. 10 Zeilen falsch erstellt worden sein, so möchte ich diese löschen.
Re: Zeilen txt löschen
Verfasst: 30.08.2017 22:07
von Mijikai
Hab mal was geschrieben
Index = Anzahl von #CRLF$ ausgehend vom Ende der Datei!
Bin davon ausgegangen das der Text in Ascii vorliegt!
Code: Alles auswählen
Procedure.i CutFilePart(File.s,Index.i)
Protected FileSize.i, Count.i, Sig.w
Protected FileHandle.i = OpenFile(#PB_Any,File)
If FileHandle
FileSize = Lof(FileHandle) - 1
While FileSize
FileSize - 1
If FileSize < 0
FileSize = 0
EndIf
FileSeek(FileHandle,FileSize)
If ReadData(FileHandle,@Sig,2)
If Sig = 2573
Count + 1
If Count = Index
TruncateFile(FileHandle)
CloseFile(FileHandle)
ProcedureReturn #True
EndIf
EndIf
Else
Break
EndIf
Wend
CloseFile(FileHandle)
EndIf
EndProcedure
Re: Zeilen txt löschen
Verfasst: 30.08.2017 22:59
von NicTheQuick
Meins ist irgendwie komplizierter geworden. Aber es funktioniert auch:
Code: Alles auswählen
EnableExplicit
Procedure.i deleteLastLines(file.s, lines.i, blockSize.i = 4096)
Protected fileId.i, fileSize.q, filePos.q, *p.Ascii, lastChar.i = #True
Protected *mem = AllocateMemory(blockSize)
If Not *mem
ProcedureReturn #False
EndIf
fileId = OpenFile(#PB_Any, file)
If Not fileId
ProcedureReturn #False
EndIf
fileSize = Lof(fileId)
filePos = fileSize
Repeat
filePos - blockSize
If filePos < 0
blockSize = filePos + blockSize
filePos = 0
EndIf
FileSeek(fileId, filePos)
ReadData(fileId, *mem, blockSize)
*p = *mem + blockSize - 1
While *p >= *mem
If *p\a = 10 Or lastChar
If lines = 0
Break
EndIf
lines - 1
lastChar = #False
EndIf
*p - 1
Wend
Until lines = 0
FreeMemory(*mem)
filePos + (*p - *mem + 1)
FileSeek(fileId, filePos)
TruncateFile(fileId)
CloseFile(fileId)
ProcedureReturn #True
EndProcedure
deleteLastLines("/home/nicolas/tmp/purebasic/zeilen.txt", 10)
Edit: Achso, es arbeitet jetzt nur mit Linefeeds. Man müsste "If *p\a = 10" durch "If *p\a = 13" ersetzen, wenn es mit Carriage Returns funktionieren soll.
Re: Zeilen txt löschen
Verfasst: 30.08.2017 23:14
von Mijikai
Nice @NicTheQuick
Ein Performancetest wäre jetzt interessant

Bei großen Dateien sollte deleteLastLines() schneller sein da die Chunks viel größer sind.
Re: Zeilen txt löschen
Verfasst: 31.08.2017 06:13
von Fanpost
Vielen Dank ! Damit kann ich etwas anfangen. Funktioniert Super!
Re: Zeilen txt löschen
Verfasst: 31.08.2017 09:50
von NicTheQuick
Übrigens: Wer Linux nutzt, kann es einfach so machen:
Code: Alles auswählen
nicolas@tp-w530:~/tmp/purebasic$ head -n -10 zeilen.txt > zeilen_truncated.txt
Die Datei 'zeilen.txt' wird gelesen und die die Datei 'zeilen_truncated.txt' wird erstellt und hat dann 10 Zeilen weniger als die Eingangsdatei.
In Place geht das allerdings nicht. Das könnte man vielleicht noch mit 'sed' hinbekommen, aber das wäre sicherlich wesentlich umständlicher.