Zeilen txt löschen

Anfängerfragen zum Programmieren mit PureBasic.
Fanpost
Beiträge: 97
Registriert: 27.01.2013 14:43

Re: Zeilen txt löschen

Beitrag 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.
Benutzeravatar
Mijikai
Beiträge: 754
Registriert: 25.09.2016 01:42

Re: Zeilen txt löschen

Beitrag 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
Benutzeravatar
NicTheQuick
Ein Admin
Beiträge: 8679
Registriert: 29.08.2004 20:20
Computerausstattung: Ryzen 7 5800X, 32 GB DDR4-3200
Ubuntu 22.04.3 LTS
GeForce RTX 3080 Ti
Wohnort: Saarbrücken
Kontaktdaten:

Re: Zeilen txt löschen

Beitrag 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.
Bild
Benutzeravatar
Mijikai
Beiträge: 754
Registriert: 25.09.2016 01:42

Re: Zeilen txt löschen

Beitrag von Mijikai »

Nice @NicTheQuick
Ein Performancetest wäre jetzt interessant :D
Bei großen Dateien sollte deleteLastLines() schneller sein da die Chunks viel größer sind.
Fanpost
Beiträge: 97
Registriert: 27.01.2013 14:43

Re: Zeilen txt löschen

Beitrag von Fanpost »

Vielen Dank ! Damit kann ich etwas anfangen. Funktioniert Super!
Benutzeravatar
NicTheQuick
Ein Admin
Beiträge: 8679
Registriert: 29.08.2004 20:20
Computerausstattung: Ryzen 7 5800X, 32 GB DDR4-3200
Ubuntu 22.04.3 LTS
GeForce RTX 3080 Ti
Wohnort: Saarbrücken
Kontaktdaten:

Re: Zeilen txt löschen

Beitrag 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.
Bild
Antworten