Trick 72: Bedenke wohl die letzte Zeile ...  
                Was steht am Ende einer Datei?

Aufgabe: Schnell mal eben die letzte Zeile / die letzten 100 Bytes
             einer Datei besorgen

Warum: Hat man eine Datei produziert oder von woanders bezogen, kann
           es nützlich sein, sich mal das Ende anzuschauen.
 
Die Probleme damit sind weit größer als mit der ersten Zeile, aber mit
diesen Hinweisen geht es auch bei extrem großen Dateien sehr schnell.
Eine Datei mit 250MB kriegt man kaum in einen Editor...
Trickreich ist es vor allem wegen der Steuerzeichen! Hier finden Sie
ein paar erprobte Rezepte zum Abkupfern. Ganz unten ein fertiger FLEX,
mit dem man sofort die letzte Zeile jeder Datei sehen kann.

Ist die Datei xyz.txt sehr klein, sagen wir mal unter 10000 Zeichen,
lautet das schnellste, einfachste Rezept so:

var Fxyz.txt
var (0,r10000)
var (9900,0)

und schon hat man die letzten 100 Bytes. Der Trick  ist:
Der Dateitext wird nach dem Einlesen in der iV nach rechts geschoben,
so daß eine Zeichenfolge von 10000 Byte entsteht, der eigentliche
Text ganz am Ende. So kann man den Abschnitt ab Position 9900 nehmen,
das sind dann genau die letzten 100 Zeichen. (Es gibt leider keinen
Manipulationsbefehl, der direkt die letzen 100 Byte herausgriffe.)
Hierbei erhält man alle Zeichen, auch die Leer- und Steuerzeichen,
also vor allem 13 und 10, die sich am Ende befinden.

Wenn man aber genau die letzte Zeile will, und nicht weiß, wie lang
diese ist, kann man es so machen:

var Fxyz.txt
var (T"^J" e"^M")


Der Manipulationsbefehl (T"^J" nimmt das hinter dem letzten Code 10
stehende Stück, und das ist die letzte Zeile. Mit ^J ist nicht der
Code 10 gemeint, sondern man gibt die Zeichen ^ und J getrennt an.
Das Programm interpretiert das so, daß der Code 10 gesucht werden soll.

Moment, sagen Schlauköpfe jetzt, die letzte Zeile kann leer sein,
oder es gibt am Ende sogar mehrere Leerzeilen mit oder ohne Blanks.
aber man will natürlich die letzte echte Textzeile haben! Was dann?
Da hilft dieser Trick:

ins _^M^J_{{{_
var (F" {" T"{{{")

Damit werden erst einmal alle Kombinationen 13 10 durch {{{ ersetzt,
dann am Ende die Zeichen { und Blank weggenommen - egal wie viele es
sind,  und dann im verbleibenden Text nach der letzten Sequenz {{{
gesucht und der dahinter stehende Text genommen. Das ist die letzte
Zeile, in der was steht.

Nur bei Dateien oberhalb 10000 Byte Länge empfiehlt sich das weniger.
Es gibt eine viel schnellere Methode. Sagen wir, die Datei ist
wieder xyz.txt. Dann ist dies das geeignete UP, um die letzte Zeile
anzeigen zu lassen:


  ---------------------------------------------------------------------
  LASTLINE.FLX
  Aufruf:  X dateiname  (d.h. dateiname steht dann in der iV)

perf lastline
mes
end

  Unterprogramm "Letzte Zeile nach iV holen"
  Funktioniert bei allen Konfigurationen.
:lastline
  Name steht in iV
ins #upA
fsize
if no var "DATEI " #upA " NICHT GEFUNDEN";return
ins #upL
var #upA
open
  Dateilaenge minus -1000
eval #upL -1000
  positionieren
fetch m
   1000 Bytes holen (d.h. gesamten Rest der Datei)
      laenger wird die letzte Zeile ja wohl nicht sein?
fetch 1000
  13 10 durch {{{ ersetzen (fetch macht ^ und M aus Code 13)
  Wenn man aber das Zeichen ^ suchen und ersetzen will,
  dann muss man  ^~  angeben
ins _^~M^~J_{{{_
var (F" {" T"{{{")
close
return
  ---------------------------------------------------------------------

Nochmal langsam zum Mitschreiben, warum hier ^~M  statt ^M usw.?
Weil der Befehl "fetch m" die Steuerzeichen in Codierungen der Form ^X
verwandelt, also jeweils zwei Zeichen draus macht, d.h. aus 13 wird ein
^ und ein M. Bei  var Fxyz.txt  ist das nicht so, da bleiben 13 und 10
als solche erhalten, als einzelne Codes also. Das "Suchen und Ersetzen
mit dem Befehl  ins _..._..._  erfordert bei dem Spezialfall des
Zeichens ^, daß man dafür ^~ angibt. Solche Sonderfälle sind immer
ärgerlich, aber das UP kann man immerhin ohne dieses Wissen verwenden.

Anm.:
Ab V28.4 wird man auch sagen können:
var (F"^~ MJ")
um hinten direkt die Zeichen  ^  und  M  und  J  alle wegzunehmen.
(Bis jetzt geht ^~ bei F"..." und f"..." nicht.)