Manuals zur bish

bish(K)
cat(K)
crc(K)
cut(K)
echo(K)
expr(K)
grep(K)
bgrep(K)
line(K)
wc(K)
cmp(K)
rel(K)
tr(K)
test(K)
tee(K)
coder(K)
man(K)
xregexp(R)
regexp(R)
ansi(R)
readc(K)
calc(K)
comx(K)
dat(K)
dd(K)
hx(K)
ov(K)
pg(K)
timex(K)
touch(K)
vi(S)
bish(V)

Copyright © 1995-2018 Helmut Schellong


^

 bish(K)                                                                bish(K)



 NAME
      bish.exe - Shell-Programm, Kommando-Programmiersprache


 SYNTAX
      bish  [-afhinpstuvxBCEINOPSUX9!] [-o opt]... [-c str] [datei [arg ...]]



 BESCHREIBUNG
      bish  ist ein Kommando-Interpreter, der Kommandos von der Tastatur,
      von einem String-Argument, von der Standard-Eingabe (handle 0)
      oder aus einer Datei liest und ausführt.
      bish  stellt eine leistungsfähige Programmiersprache zur Verfügung,
      die sich u.a. sehr wesentlich am Exit-Code von Kommandos orientiert.
      Daneben gibt es viele nützliche eingebaute Kommandos.
      Für die Syntax in  bish  dient die Syntax der  ksh  als Leitlinie.
      Zwischen dem später beschriebenen set-Kommando und dem Aufruf der
      bish besteht eine starke Verwandtschaft bezüglich der Optionen.
      bish  ist insgesamt ein äußerst leistungsfähiges Shell-Programm.
      Zusätzliche Eigenschaften der bish, über die die ksh nicht verfügt,
      sind nachfolgend durch (-Z-) gekennzeichnet.
      Zum Thema Kompatibilität siehe bish(I).
      Es lohnt sich, nachfolgend nach BISHAUTOR und BISHPROGRAM zu suchen.

      Der Name 'bish' ist eine Abkürzung von BInarySHell und BuiltInSHell.
      Beides ist voll zutreffend.
      Kommando-Argumente sind null-terminiert und das einzige wesentliche
      Merkmal, das nicht binär arbeitet.
      Variablen und vieles mehr sind allerdings binär konzeptioniert.
      Es kann eine Variable mit einer Null als Inhalt in ein Argument eingebaut
      werden. Das funktioniert auch. Jedoch lesen die Kommandos nur bis zur
      ersten Null im Argument.
      Das Konzept des Kommandos an sich wurde intensiv realisiert.
      So können Kommandos Variablennamen entgegen nehmen und selbständig deren
      Inhalt besorgen und lesen, auch Null-Bytes darin.


    Definitionen
      Spezialzeichen     ;  &  (  )  |  <  >  NL  SP  TAB
                         NL    Zeilenvorschub ([CR-]new-line)
                         SP    Leerzeichen (space)
                         TAB   Tabulator-Zeichen

      Zwischenraum=      SPACE  TAB  (NL)
      zeichen

      Sonderzeichen      #   =   $ ` ~   ? * [   % " '   { }   :

      Zeichenfolgen mit operativer Bedeutung:
                         ''  %NL   &&  ||  &|   $(  )   $((  ))
                         |!  |2   `-  $(-   :-  :+  :=
                         [[  ]]   {{  }}   ;;  ;,  () {  ()) {
                         ${ }  ${# }  ${: }  ${@ }  ${{ }  ${{# }}

      Name           Alphanumerische Zeichenfolge plus Unterstrich (_) :
                     A-Za-z_0-9 .
                     Ein Digit (0-9) darf nicht erstes Zeichen sein.
                     Dient als Bezeichner von Shell-Variablen und -Funktionen.
                     Namelänge maximal 31 Zeichen.

      Wort           Zeichenfolge, ggf. aufgeteilt durch eines oder mehrere
                     nichtmaskierte Spezialzeichen.

      Kommando       Zeichenfolge gemäß bish-Syntax, bestehend aus einem oder
                     mehreren Wörtern (Argumente), die von der Shell
                     interpretiert und ggf. expandiert bzw. ersetzt werden.
                     Die Shell liest jedes Kommando und führt es als
                     internes oder externes Kommando aus.

      #              Leitet einen Kommentar ein.
                     Diejenigen Zeichen ab und einschließlich # bis
                     ausschließlich NL werden ignoriert.
                     # wirkt nur als erstes Zeichen eines Argumentes,
                     also nur nach NL oder anderen Trennzeichen, oder am
                     Dateianfang. Andernfalls ist es ein normales Zeichen.
                     Die Shell verarbeitet sämtliche Zeichen, mit Ausnahme
                     der beiden mit den Dezimalwerten 0 und 255 (und ^Z).

    Kurzerklärung der Zeichen
      ;  NL  (&)        Trennen Kommandos (und Pipes,Listen) voneinander
      &                 Startet ein externes Kommando im Hintergrund
      SPACE  TAB        Trennen Argumente voneinander
      &&  ||  &|        Exit-Code-abhängige Verkettung von Kommandos
      |   |!  |2 (|h)   Verknüpfung von Aus- und Eingabe von Kommandos (Pipe)
      > >> < << <>      Umlenkung von Aus- und Eingabe von Kommandos
      {...}  {{...}}    Zusammenfassung von Kommandos
      $(...)  `...`     Einsetzung der Ausgabe von Kommandos
      $(-..)  `-..`     Einsetzung der Ausgabe von Kommandos
      $..  ${..}        Einsetzung eines Variablen- oder Parameterinhalts
      ${{..}            Indirekter Zugriff  (1-fach indirekt)
      ${{..}}           Indirekter Zugriff  (1-fach indirekt)
      ${#..}            Einsetzung einer Variablen- oder Parameterinhaltslänge
      ${:..}            Einsetzung einer Variablenspeichergröße
      ${@..}            Einsetzung einer Variablenadresse
      ${{{#..}          Indirekter Zugriff  (2-fach indirekt)
      ${{{#..}}}        Indirekter Zugriff  (2-fach indirekt)
      $s                Einsetzung von (Steuer-)Werten (s==[*@?!$-]}...])
      ${..:x..}         Entweder/Oder-Einsetzung
      $((...))          Einsetzung des Resultats eines arithmetischen Ausdrucks
      ?  *  [           Einsetzung von passenden Dateinamen (Wildcards)
      name[i]           Arrays
      ((...))           Berechnung eines arithmetischen Ausdrucks
      (...)             Sub-Shell-Aufruf
      ".."  '..'  %     Maskierende Einfassungen und Maskierzeichen
      =                 Variablen-Zuweisung
      name:znnnn        Variablen-Füllen mit nnnn-mal zeichen
      name:w.nnnn       Variablen-Füllen mit nnnn-mal wert
      ;;  ;,            Beenden eine Kommando-Folge beim case-Kommando
      fname()  {   }    Definition einer Shell-Funktion
      fname()) {  )}    Definition einer (verschachtelten) Shell-Funktion
      %NL               Zeilenverlängerung
      #                 Kommentar-Zeichen
      label:            goto-Marke
      :                 Leer-Kommando
      [[...]]  [...]    Symbolische Syntax des test-Kommandos
      ! kommando        Invertierung des Exit-Codes
      ^.*[^a-b]%{a,b%}  Reguläre Ausdrücke = Super-Wildcards
       %(%)%1%9$        Reguläre Ausdrücke = Super-Wildcards



    Speicher-Management
      Ab Version 4.00 wird Speicher dynamisch besorgt.
      Deshalb wurden manche Startwerte (MIN) gesenkt, jedoch immens hohe
      Maximallimits gesetzt.

      In [Byte], dezimal:
      -------------------
      BEZEICHNUNG     MIN         IST         MAX       ADRESSE      ADR_ALT
      12#  echo "$__MEM__"
      FUDEFSs         1024        1024       16384   34370330624  34370330624
      FUDEFSp         2048        2048       32768   34370342912  34370342912
      NAMDEFS        16384       16384      262144   34370364032  34370364032
      VARBUF         49152       49152   536870912   34370497216  34370497216
      VARBUFl         4096        4096    67108864   34370383872  34370383872
      ARGS           65536       65536   536870912   34370426816  34370426816
      ARGBUF         65536       65536   536870912   34370549760  34370549760

      In [Byte bzw. Anzahl]:
      ----------------------
      13#  ver l
      pnlen=1024 fnlen=255 dirslen=1024 namlen=31 
      njmp=16 npipes=64 ibufsz=2048 
      fudefs_min=256 fudefs=256 fudefs_max=4096 
      namdefs_min=512 namdefs=512 namdefs_max=8192 
      namdefsl_min=48 namdefsl=48 namdefsl_max=48 
      vbufsz_min=49152 vbufsz=49152 vbufsz_max=536870912 
      vbufszl_min=4096 vbufszl=4096 vbufszl_max=67108864 
      abufsz_min=65536 abufsz=65536 abufsz_max=536870912 
      nargs_min=8192 nargs=8192 nargs_max=67108864 

      Die Anzahl der lokalen Namen ist konstant und relativ gering,
      weil das ein Geschwindigkeitsmerkmal ist.
      Bei Bedarf können sehr große Variablen als Quasi-Array angelegt
      werden und mit catv (binär) bearbeitet werden.
      Nach Fehlermeldungen in der interaktiven Kommandozeile
      werden die beiden Argumentespeicher auf MIN gesetzt.

      FreeBSD:
      --------
      time csh  -c "echo /usr/*/*/*/* >> /dev/null"
      time bash -c "echo /usr/*/*/*/* >> /dev/null"
      time sh   -c "echo /usr/*/*/*/* >> /dev/null"
      time bish -c "echo /usr/*/*/*/* >> /dev/null"
             21.57 real        18.21 user         2.74 sys
              5.84 real         4.80 user         0.87 sys
              1.35 real         0.52 user         0.78 sys
              1.21 real         0.28 user         0.87 sys
      time bash -c "echo /usr/*/*/*/*  | wc"
      time bish -c "echo /usr/*/*/*/*  | wc"
      time bish -c "echo /usr/*/*/*/*" | wc
             82.43 real        79.13 user         0.89 sys
              1.58 real         0.32 user         0.95 sys
              1.37 real         0.25 user         0.91 sys
             1   80377 2916481
             1   80424 2918325
             1   80426 2918382
      bish expandiert bei * auch .namen

      Beispiele:
      ----------
      Je nach MAX kann eine Variable auch mit 100 Millionen
      Bytes (hier 'a') gefüllt werden:
           set Buf:a100000000        #dauert beispw. ~0.5 s
      Kontrolle:
           echo ${#Buf}
           echo "$__MEM__"
      und nachfolgend in eine Datei geschrieben werden:
           catv Buf >datei
      Füllen mit nnnnn(n) Pfadnamen:
           Pfade=/usr/*/*/*/*
      Dies sind in der Regel mehrere MByte.



    Kommandos
      Ein 'normales' Kommando ist eine Folge von Wörtern, die durch
      Zwischenraumzeichen getrennt sind.
      Diese Kommandowörter geben die Argumente direkt als Konstanten an
      oder sie werden durch die Shell-Interpretation zu Argumenten umgebildet.
      Das erste Argument (Arg0) ist der Name des Kommandos, die ggf. weiteren
      sind die eigentlichen Argumente zu dem Kommando.
      Der (Rückgabe-)Wert eines Kommandos ist sein Exit-Code.
      Dieser ist gewöhnlich 0 (=TRUE!) bei bestimmungsgemäßer Funktion
      des Kommandos. Um dem Exit-Code einen Informationsgehalt zuzuweisen,
      der für Steuerzwecke genutzt werden kann, werden Werte zwischen
      0 und 127 explizit von Kommandos selbst gesetzt.
      Kommandos werden voneinander getrennt u.a. durch die Zeichen NL und ;

      Das Zeichen  !  vor einem Kommando (! Kdo) bewirkt, daß nach Ausführung
      des jeweiligen Kommandos der globale Exit-Code invertiert wird.
      Siehe auch Kommando 'inv'.
      Es wird nicht geprüft, ob ein Kommando einen Exit-Code hat.

      Eine Pipeline ist eine Folge von einem oder mehreren Kommandos, die
      (bei mehr als einem)  durch  |  getrennt sind.
      Die Standard-Ausgabe eines Kommandos vor | wird mit der Standard-Eingabe
      des | folgenden Kommandos verknüpft:   kdo1 | kdo2 [ | kdo3 ]...
      NL und ;  dürfen nicht VOR  |  stehen.
      Der Wert einer Pipeline ist der Exit-Code des letzten Kommandos
      in der Pipeline.
      Zusätzlich gelten die Zeichenfolgen  |!  |2  |h  (h=0...9),       (-Z-)
      wobei durch  |!  die Standard-Fehlerausgabe zusätzlich zum nachfolgenden
      Kommando gelenkt wird und  |h  nur den explizit angegebenen Handle
      umlenkt.
      Die Zeichen  ! und 0...9  haben nur direkt nach einem unmaskierten
      Zeichen  |  diese Spezialbedeutung.
      Anm.:
      Schleifen (...done | ...), Blöcke ({...} | ...), etc., können -als
      ganzes betrachtet- nicht in eine Pipeline hinein schreiben!
      Umlenkungen, die ein Vorauslesen erfordern, über die Argumente eines
      'normalen' Kommandos hinaus, kann die bish nicht.

      Eine Liste ist eine Folge von einer oder mehreren Pipelines, die
      durch  NL  ;  &&  oder  ||  getrennt sind.
      NL und ;  dürfen nicht VOR  && und ||  stehen.
      Der Operator  && (||)  bewirkt, daß eine nachfolgende Pipeline nur
      ausgeführt wird, wenn der Wert (Exit-Code) der davorstehenden
      Pipeline  Null=TRUE (Nicht-Null=FALSE)  war.
      Eine durch  && (||)  getrennte Pipeline-Folge wird abgebrochen, sobald
      zum Operator  && (||)  Exit=Null (=Nicht-Null)  nicht mehr auftritt.
      Zusammenfassungen per  { Liste; } (s.u.)  sind möglich.

      Der Oder-Operator  &|  ist nicht kompatibel mit bekannten UNIX-Shells.
      Er hat Vorrang vor  && und ||  und bewertet den Exit-Code der Pipelines
      links und rechts von ihm.   (-Z-)
      Eine Folge von Pipelines, getrennt durch &|, ist erfolgreich, sobald ein
      TRUE-Exit auftritt. Restliche Kommandos innerhalb einer solchen
      Oder-Kette werden nicht mehr ausgeführt, nach einem TRUE-Exit.
      Der Exit-Wert einer Oder-Kette wird aufbewahrt, bis zu einem optionalen
      Operator  && oder ||, bei dem entsprechend fortgefahren wird.
      && oder || können auch vor einer Oder-Kette stehen, mit Wirkung auf alle
      durch  &&,||,&|  getrennten nachfolgenden Kommandos.
      Zusammenfassungen per  { Liste; } (s.u.)  sind möglich.
      Beispiel:
           *false  ||  *true  &|  false &|  false  &&  *kdo
           *true   &&  *false &| *true  &|  false  &&  *kdo
           *true   &&  *false &| *true  &|  false  ||   kdo
           *true   &&  *false &| *false &| *false  ||  *kdo
           *true   &&  *false &| *false &| *false  &&   kdo
           *true   ||   false &|  false &|  false  &&   kdo
      Ausgeführte Kommandos wurden mit * gekennzeichnet.
      In diesem Zusammenhang ist auch das Kommando 'inv' nützlich,
      das Exit-Werte invertiert.
      Mit den Operatoren && || &| {...} und inv,true,false
      können lange Verarbeitungsketten auch mit if-else-Effekten
      gebildet werden.


      Die Pipelines arbeiten in Voreinstellung mit temporären Dateien,
      genau: mit seek-baren, verschachtelten Dateiendabschnitten,
      wahlweise (per -U, set -U) mit der Funktion pipe().
      Das hat mehr Vorteile als pipe() Vorteile hat:
           o  Nicht nur externe Kommandos in der pipe-Kette, sondern
              auch interne und Shell-Funktionen normal möglich.
           o  Argumente zu internen Kommandos dürfen tausendfach
              länger sein als die zu anderen Prozessen.
           o  Funktioniert mit allen Betriebssystemen.
           o  Man erhält eine temporäre Datei 'on the fly'.
           o  Diese Datei kann mittels 'seek' mehrfach gelesen werden.
           o  Es gibt keine (Lese-)Probleme mit Kommandos, die bei
              'echten' pipe()s versagen.
              (Kommandos, die keine ausdrücklichen Filterkommandos sind.)
           o  Die Prozesse werden nacheinander gestartet,
           o  sie können sich nicht gegenseitig stören,
           o  die momentane Prozeßlast ist geringer,
           o  der Exit ist von jedem in der Kette eindeutig erhältlich.
           o  Kommando  a | b  kann eine Variable -zum Schluß- setzen,
              die -danach- von Kommando b ausgewertet wird.
           o  SIGPIPE kann nicht vorkommen, bei vorzeitigem Beenden
              eines Kommandos in der Pipe.
           o  Beliebige gewollte Rückwirkungen aus der Pipe-Kette
              heraus sind möglich (nur 1 Prozeßkontext).
      Vorteile von pipe():
           o  Der Datenstrom darf beliebig groß sein.
           o  Arbeitet deutlich/mehrfach/vielfach schneller,
              zumindest bei großen Datenmengen pro Vorgang.
           o  Permanentes Monitoring ist möglich.
      Echte Pipelines per  -U/+U und set -/+U  nur unter Unix.
      (Siehe set-Kommando)

      Beispiel Geschwindigkeit:
      -------------------------
      time bish -pU -c "cat /usr/ARCH/3.tar | sumv -l"
      time bish -pU -c "cat /usr/ARCH/3.tar | sumv -l"
      time bish -p  -c "cat /usr/ARCH/3.tar | sumv -l"
      time bish -p  -c "sumv -l < /usr/ARCH/3.tar"
      16580123892488523
            1.99 real         0.06 user         0.26 sys
            0.28 real         0.04 user         0.22 sys
            4.99 real         0.07 user         1.56 sys
            0.19 real         0.04 user         0.13 sys
      (Datei 3.tar == 50 MB)




      Spezial-Kommandos zur Ablaufsteuerung (Intern):
      Der Wert dieser Kommandos ist der Wert des innerhalb dieser Kommandos
      zuletzt ausgeführten 'normalen' Kommandos, wenn nicht anders angegeben.

      for  Name  [ in  Wort ... ]
      do
        Liste
      done
                  Name wird nacheinander auf alle Argumente gesetzt,
                  die in der Wort-Liste enthalten sind, und Liste wird dann
                  jeweils mit einem solchen Argumentwert einmal ausgeführt.
                  Wenn ``in Wort'' fehlt, wird die Liste zwischen do und done
                  mit jedem positionalen Parameter einmal ausgeführt.
                  ``in "$@"'' entspricht der Weglassung.

      for  N  Name ...  in  [ Wort ... ]
      do
        Liste
      done
                  Diese Erweiterung (N) ist nicht kompatibel mit bekannten
                  UNIX-Shells.   (-Z-)
                  N ist eine positive Zahl größer Null und gibt die Anzahl
                  der Variablennamen an, die jeweils mit entsprechend vielen
                  Argumenten aus der Wort-Liste gefüllt werden sollen.
                  Es müssen entsprechend viele Namen angegeben werden.
                  Der Platzhalter-Name '-' ist zugelassen. (s. read)

                  Die Variable __ARGS__ wird für Kontrollzwecke auf die
                  jeweilige Anzahl der überwiesenen Argumente gesetzt, weil
                  diese zum Schluß (Rest!) kleiner sein kann als das
                  angegebene N.
                  Überzählige Variablen werden leer ("") gesetzt.
                  $__ARGS__ summiert ergibt stets die Anzahl der Argumente,
                  die in der Wort-Liste enthalten sind.

                  Die vorstehend beschriebene Erweiterung der for-Schleife
                  ist vorzüglich für die Bearbeitung von Tabellen
                  im weitesten Sinne geeignet. Siehe bish(B).


      [ for Name ] [ from a ] [ by i ] [ to b ] repeat
      do
        Liste
      done
                  Diese zweite Form der for-Schleife kann mit jedem der
                  fünf genannten Schlüsselworte beginnen, und ist nicht
                  kompatibel mit bekannten UNIX-Shells.   (-Z-)
                  Wird ``for Name'' angegeben, ist Name innerhalb von
                  Liste verfügbar, mit einem Digit-String als Inhalt,
                  der von einer internen Laufvariablen gespeist wird,
                  die mit `a' startet, nach jedem Durchlauf um `i' erhöht
                  bzw. vermindert wird, und mit `<=b' bzw. `>=b' letztmalig
                  durchläuft.
                  Voreingestellt sind:
                       for   interne_laufvariable
                       from  1
                       by    1
                       to    ×  (unendlich,infinite)
                  Die interne Laufvariable ist vom Typ long-Integer, 32 Bit
                  oder 64 Bit.
                  Beispiel:
                       to 5 repeat
                       do
                         Liste
                       done
                  Liste wird 5-mal ausgeführt.
                  Man sollte anstelle von 'for Name' (erste Form von for)
                  die explizite Darstellung 'for Name in $*' wählen,
                  weil ein positionaler Parameter das Wort 'repeat'
                  enthalten könnte. In solch einem Fall könnten die beiden
                  for-Variationen nicht mehr eindeutig erkannt werden.


      case  Wort  in
        pattern[|pattern]...)  Liste;;
        pattern[|pattern]...)  Liste;,
        pattern[|pattern]...)  Liste
                               ;;
        pattern[|pattern]...)  Liste;;
        ...
      esac
                  Es wird diejenige Liste ausgeführt, hinter demjenigen
                  Suchmuster (pattern), das -von oben nach unten (und von
                  links nach rechts)- zuerst zum Wort paßt.
                  Die Zeichenfolgen  | ) ;; ;,  gehören zur Syntax.
                  Wenn als Listenabschluß ;, statt ;; gegeben wird, erfolgt
                  ein Sprung zum nächsten Listenbeginn (fallthrough) (-Z-),
                  anstelle eines Sprunges hinter 'esac'.
                  (Siehe auch unten Kommando 'goend'.)
                  Ein Listenabschluß ist gleichzeitig eine Markierung, die
                  darauf hinweist, daß nun ein Pattern oder esac folgt.
                  Hinter den Listenabschlüssen dürfen nur NL oder
                  Zwischenraumzeichen stehen.
                  Direkt hinter esac muß NL oder Zwischenraum folgen.
                  Der Mechanismus bei den Pattern entspricht dem
                  bei der Dateinamenexpansion (s. regexp®).
                  Expansionszeichen sind  ? * [  .
                  Zusätzlich gibt es eine ODER-Funktion per | .
                  Innerhalb eines Patterns haben nur die Zeichen
                       %  |  )
                  neben den Expansionszeichen Spezialbedeutung.
                  )  beendet ein Pattern.
                  %  maskiert die Spezialzeichen und Zwischenraumzeichen.
                  Die Folge  %NL bzw. %CRNL  wird ignoriert/weggeworfen.
                  Pattern müssen Konstanten sein.
                  Das Kommentarzeichen # muß nur maskiert werden, wenn man es
                  als erstes Pattern-Zeichen bewertet haben will, andernfalls
                  nimmt es an dieser vordersten Position die Zeile weg.
                  Man beachte bei Kommentar-Kennzeichnungen NACH ')'
                       ...)  #...
                  daß die Listenabschlüsse aktiv bleiben!

      if  liste
      then
        Liste
      [elif  liste
       then
         Liste]...
      [else
         Liste]
      fi
                  Die Liste hinter if wird ausgeführt und, falls TRUE,
                  dann die Liste nach dem ersten then.
                  Andernfalls die Liste nach elif und, falls TRUE, dann
                  die Liste nach dem nächsten then (soweit elif vorhanden).
                  Ansonsten die Liste nach else (soweit else vorhanden).
                  Wenn keine then- oder else-Liste ausgeführt wurde, ist
                  der Wert des if-Kommandos TRUE.
                  (Siehe auch unten Kommando 'goend'.)

      while  liste      until  liste
      do                do
        Liste             Liste
      done              done
                  Die Liste zwischen do und done wird (wiederholt) ausgeführt,
                  solange die Liste nach while TRUE bzw. die Liste nach until
                  FALSE als Wert liefert.
                  while und until liefern TRUE, wenn keine do-Liste
                  ausgeführt wurde.

      break [n]
                  Verläßt die umgebende(n) for-, while- oder until-Schleife(n).
                  Multilevel-break bei n>1. Wird ignoriert bei n=0;
                  Ohne Angabe von n gilt n=1.

      continue [n]
                  Lenkt die Verarbeitung zum Startpunkt der umgebenden
                  Schleife. Multilevel-continue bei n>1.
                  Wird ignoriert bei n=0; Ohne Angabe von n gilt n=1.

      goend [n]
                  Verläßt das/die umgebende(n) if- oder case-Kommando(s).
                  Multilevel-goend bei n>1. Wird ignoriert bei n=0;
                  Ohne Angabe von n gilt n=1.        (-Z-)   (s.u.: goto)

      break und goend setzen nicht den Exit-Wert.
      break und continue beziehen sich nur auf Schleifen, goend nur
      auf if und case. Das heißt z.B., ein goend 1 verläßt beliebig viele
      Schleifen und einen case auf einmal, wenn die Schleifen sich
      verschachtelt in einem case befinden!
      FOLGENDE EINSCHRÄNKUNGEN WURDEN BESEITIGT:
      Die Listen (liste) nach  while, until, if und elif  betreffend,
      gibt es (üblicherweise) Einschränkungen bezüglich der Kommandos
      break [n], continue [n] und goend [n], bei n=1 und/oder n>1.
      Diese Kommandos dürfen sich dort nur auf Körper beziehen, die
      sich selbst auch dort befinden.
      Das gilt nicht für die Listen nach  do, then und else, denn diese
      sind die eigentlichen Arbeits-Listen.

      Hinter:
           done  fi  esac
      dürfen TAB und/oder Leerzeichen stehen.
      Es muß ein Zeilenvorschub, Semikolon (;), Kommentar (#) oder EOF folgen.


      Die folgenden Schlüsselwörter müssen an der Position eines
      Kommandonamens stehen, bzw. als Einzelargument plaziert werden.
      Andernfalls werden sie nicht als Schlüsselwort erkannt:

           if then else elif fi case esac for while until do done time
           { } {{ }} [ ] [[ ]] in  from by to repeat


      (-Liste)       Liste wird in einer Subshell ausgeführt.
                     Entspricht etwa:   bish -c "Liste"      (-Z-)
                     Die Subshell erbt keine Daten der Shell.
                     Die Klammern wirken nahezu wie ("Liste") .
                     Für Liste gilt hier ein Längenlimit von 2 KB.
                     Nach der Klammer ( haben nur folgende Zeichen
                     Spezialbedeutung:   %  $  `  )
                     Diese Maskierung gilt nur für die die Subshell
                     aufrufende Shell.
                     Beispiel:
                          echo aaaaa(echo sss%%%)sss)AAAAA
                     Subshell-Input:
                          echo sss%)sss
                     Ausgabe:
                          sss)sss
                          aaaaaAAAAA
                     Beispiel:
                          (cd \dos; DIR)
                     Nur die Subshell wechselt das Directory!

      (Liste)        Liste wird unix-like in einer Subshell ausgeführt.
                     Für die Subshell wird eine Prozeßkopie hergestellt.
                     Die Subshell erbt alle Daten der Shell.
                     Diese Original-Variante ist nur unter Unix verfügbar.
                     Die Klammern wirken nahezu wie ('Liste') .
                     Nach der Klammer ( haben nur folgende Zeichen
                     Spezialbedeutung:   %  )
                     Diese Maskierung gilt nur für die die Subshell
                     aufrufende Shell.
                     Für Liste gilt hier ein Längenlimit von 2 KB, da
                     der Liste-Text im Input-Buffer ausgeführt wird.
                     Allgemein darf Liste allerdings unbegrenzt lang sein.
                     Beispiel:
                          ( echo %%%) )
                          )
                     Beispiel:
                       ( echo abc;sleep 20; ( echo erf;sleep 20;echo uvw %) )
                       1512 root  9480K   996K wait    1   0:00   0.00% bish
                       1556 root  9480K   992K wait    0   0:00   0.00% bish
                       1557 root  9480K  1000K nanslp  0   0:00   0.00% bish
                     Vorstehend eine verschachtelte Subshell.
                     Entsprechend sind zeitweise 3 bish-Prozesse zu beobachten.
                     Der Sinn der Maskierung wird sichtbar.
                     Beispiel:
                          a=zzz
                          (- echo Z$a )
                          Zzzz
                          (- a=iii; echo Z$a )
                          Zzzz
                          (- a=iii; echo Z%$a )
                          Ziii
                          ( echo Z$a )
                          Zzzz
                          ( a=iii; echo Z$a )
                          Ziii
                     Es ist erkennbar, daß die Variante (Liste) die Daten
                     der Shell erbt. Die Shell expandiert hier $a nicht.
                     Zum Schluß überschreibt die Subshell die geerbten Daten.

      { Liste;}      Liste wird ausgeführt.
                     Dient zur Blockbildung, um beispielsweise die Wirkung
                     von  &&, || oder &|  auf beliebig viele Kommandos
                     auszudehnen.

      {{ Liste;}}    (-Z-)  Wie oben. Jedoch können per local-Kommando lokale
                     Variablen definiert werden, und das global-Kommando
                     ist hierin lokal.

      [  ausdruck  ]
      [[ ausdruck ]]
                     Siehe test(K).
                     Das Kommando test ([ [[) ist ein eingebautes Kommando
                     mit einer größeren Anzahl von Test-Funktionen, das zur
                     Steuerung TRUE oder FALSE als Exit-Code zurückgibt.
                     Bei der Zwei-Klammer-Syntax haben nur folgende Zeichen
                     Spezialbedeutung:   % " '  ` $  SP TAB NL
                     Deshalb muß direkt hinter  ]]  eines der drei
                     letztgenannten Zeichen platziert werden.
                     Beispiel:
                          if [[ abc > ABC ]] ;then echo Größer; fi
                          [[ ABC > abc ]] || echo Kleiner
                          test ABC %> abc||echo Kleiner
                     Man beachte, daß wegen dieser anderen Basismaskierung
                     einige Operatoren nicht mehr explizit maskiert werden
                     müssen/dürfen.
                     Die Zwei-Klammer-Syntax stellt auch Vergleiche mit
                     pattern (*?[!a-b]) zur Verfügung:
                          [[ abc = a?c ]] && echo gleich
                          [[ abc != a*bc ]] && echo ungleich


      Name() { Liste; }        Name()) { Liste; )}

      Name() {                 Name()) {
         Liste                    Liste
      }                        )}

                     Definieren Shell-Funktionen.
                     Die Aufrufsyntax ist identisch zu der der
                     'normalen' Kommandos:   Name [Args ...]
                     Shell-Funktionen werden abgespeichert und sind
                     in dem Shell-Prozeß, in dem sie definiert wurden,
                     immer wieder ausführbar.
                     Innerhalb des Funktionskörpers sind positionale
                     Parameter entsprechend dem Funktionsaufruf zugreifbar.
                     Funktionsaufrufe dürfen beliebig verschachtelt und
                     direkt oder indirekt rekursiv sein.
                     Auch quasi-verschachtelte Definitionen sind möglich! (-Z-)
                     Funktionen müssen vor ihrem ersten -aktiven- Aufruf
                     definiert worden sein!
                     Man beachte, daß 'Liste' die gesamte Shell-Syntax zuläßt.
                     Innerhalb von Funktionen sind lokale und statisch-lokale
                     Variablen definierbar (s.u.: local, global, static (-Z-)).
                     ---
                     Die Abschlußzeichen betreffend können mehrere Syntaxformen
                     benutzt werden:
                          SP|TAB|;}NL      ohne(!) NL zuvor.
                               oder
                          NL}
                               oder
                          )}    ))}    )))}    ...
                     Die erste Form ist für Ein-Zeilen-Definitionen,
                     die zweite für große Funktionen, wobei ein unabsichtlicher
                     Abschluß innerhalb des Körpers durch Einrücken leicht
                     vermieden werden kann - was ohnehin üblich ist.
                     Die dritte Form ist universell, verlangt aber, daß die
                     Anzahl der ')' in der oben gezeigten Form angekündigt
                     wird.
                     Auf diese Weise können die Funktionskörper wesentlich
                     einfacher und schneller gelesen und gespeichert werden.
                     Denn innerhalb des Körpers dürfen { und } im anderen
                     Zusammenhang beliebig vorkommen.
                     Siehe auch return- und fprint-Kommando.
                     ---
                     Funktionen können zwar nicht direkt verschachtelt
                     definiert werden, jedoch zeitlich nacheinander!
                     Die dritte Abschlußform ist besonders dafür geeignet.
                     Grundsätzlich, wenn Shell-Syntax aktiv(!) durchlaufen
                     wird, werden Funktionen "gelernt"!
                     Man kann also durchaus Funktionsdefinitionen in einen
                     if-Zweig setzen, und diese wird global gespeichert, wenn
                     der Zweig aktiv durchlaufen wird!
                     Mit dem Kommando 'fprint' können Funktionskörper
                     ausgegeben werden. Der Inhalt darf auch beliebiger Text
                     sein, der gar nicht ausführbar ist!

      time Liste     Die Liste wird ausgeführt und die dafür benötigte
                     Zeit auf die Standard-Fehlerausgabe ausgegeben.
                     Die Zeit wird in Sekunden angegeben, weshalb bei kleinen
                     Zeitspannen 0 angezeigt wird.
                     (siehe auch timex(K))


    Tilde-Substitution
      Ein Tilde-Zeichen ~ als erstes Zeichen eines Argumentes
      wird durch den Inhalt der Environment-Variablen HOME ersetzt.

    Kommando-Substitution
      Wenn ein Kommando zwischen $( und ) oder zwischen ` und ` steht,
      wird seine Standard-Ausgabe an die Stelle dieser Ausdrücke gesetzt.
      $(Kommando)  oder  `Kommando`  wird also per Umlenkung durch den Text,
      den Kommando normalerweise auf den Bildschirm ausgeben würde, ersetzt.
      Alle Zeichen von Kommando werden so interpretiert als befände man
      sich am Prompt der Kommando-Zeile, auch wenn sich `Kommando` innerhalb
      von zwei maskierenden " befindet:  "`kdo`"     (Demaskierung!)
      Innerhalb von Kommando-Substitutionen sind also äußere Maskierungen
      -vorübergehend- unwirksam. Maskierungen innerhalb kann man beliebig
      vornehmen. Nach Abschluß der Einsetzung wird eine äußere Maskierung
      wieder gültig; der eingesetzte Text wird DANN entsprechend behandelt!
      Ein Minus-Zeichen direkt nach dem einleitenden Operator   $(-   `-
      entfernt anhängende Zeilenvorschübe vom eingesetzten Text.      (-Z-)
      Ein Substitutionsausdruck kann mehrere Kommandos enthalten, die durch
      die üblichen Zeichen getrennt werden - $(Liste) ist hier erlaubt!
      Diese Substitutionsausdrücke können ineinander verschachtelt werden;
      allerdings ` ` nicht (direkt) innerhalb von ` ` .
      (Maskierungen siehe unten)

    Arithmetik-Substitution
      $((arithmetischer_ausdruck)) wird durch das Ergebnis der Berechnung
      des Ausdrucks ersetzt.
      Siehe auch Arithmetische Berechnungen, ((arithmetischer_ausdruck))
      und Kommando  let "arithmetischer_ausdruck" ...

    Parameter-Substitution
      Wenn das Dollar-Zeichen  $  einem Namen, einem oder mehreren
      Digits oder einem der Zeichen  * @ # ? - $ !  voransteht,
      findet Parameter-Substitution statt.
      Ein durch einen Namen identifizierter Parameter ist eine
      Shell-Variable (benamter Parameter) und ist standardmäßig global.
      Parameter haben Zeichenketten beliebiger Länge als Inhalt.
      Der dafür reservierte Speicher wird dynamisch verwaltet,
      weshalb es mitunter nützlich sein kann, Variableninhalte per
      unset-Kommando freizugeben.
      Es können lokale Variablen definiert werden (s.u.: local (-Z-)).
      Vereinbarung lokaler Variablen wirkt wie ein Cache, da hier nur eine
      relativ kleine Namenmenge deklariert werden kann.
      Bei Erreichen eines Limits wird eine Reorganisation des jeweiligen
      Variablenspeichers aktiviert.  (s.u.:__VLIM__)  (s.bish(I))

      Wertzuweisung:   Name=Wert [Name=Wert] ...
      Deklaration:     Name="" Name='' Name= ...      (Inhalt=Null-String)

      Null-String-Zuweisungen:     a= b= c=;d=
      Drei Zuweisungen       :     a=aaa b=bbb;c=ccc
      Eine Zuweisung a=Wert  :     a=aaab=bbbc=ccc
      Kommando '=aaa'        :     =aaa
      Kommando '='           :     =
      Fehlerhafter Name =aaa :     =aaa=AAA
      Kommando mit 2 Argum.  :     echo = aaa
      Kommando mit 3 Argum.  :     echo aa=AA bb=BB cc=$CC     (keine Zuw.!)
      Zuweis. plus Kommandos :     A=aaa echo $A ; B=bbb;echo $B
      Zuweisung              :     echo=ohce

      Spezielle Zuweisungen (s.u. Kommandos local, set)
      local name:cn name:d.n :     c=Zeichen, d=Dezimalzahl, n=Anzahl
      set   name:cn name:d.n :     c=Zeichen, d=Dezimalzahl, n=Anzahl
      Binäre Werte per  :d.n :     d=0..255
      Dies ist Speicherbesorgungs-Syntax, mit calloc() vergleichbar.
      Normal möglich ist z.B.:  set buf:4.130000000

      Positionale Parameter werden beim Aufruf der Shell gesetzt.
      $0 enthält den Shell-Kommandonamen oder den Namen der Script-Datei.
      Für Shell-Funktionen und Shell-Script-Dateien werden ebenfalls
      positionale Parameter entsprechend der Aufrufargumente gesetzt, die
      u.a. mittels  $0, $1, $2, ..., ${23}, ...  lesbar sind, und lokal sind.

      Zugriff auf den Inhalt:

      $KOSTEN2             Shell-Variable.

      ${KOSTEN2}RG         { }, wenn der Name von nachfolgenden
                           Zeichen isoliert werden muß, die sonst als
                           Bestandteil des Namens gewertet würden.
           Geschweifte Klammern werden ebenfalls gebraucht, wenn mehr als
           ein Digit bei positionalen Parametern angegeben wird:

      $1$2$3 $4${19}       Positionale Parameter.


      Indirekter Zugriff auf Variablen-Inhalte:                   (-Z-)

      Standard-Zugriffe sind beispielsweise  $name  und  ${name} .
      Durch Hinzufügen von öffnenden geschweiften Klammern in beliebiger
      Anzahl werden entsprechend viele Indirektionen vorgenommen:
           ${{name}    ${{{name}     ${{{{name}      ${{digits}    ${{#name}
           ${{name}}   ${{{name}}}   ${{{{name}}}}   ${{digits}}   ${{#name}}
      Aus Symmetriegründen können auch gleich viele schließende Klammern
      angegeben werden.
           ${{{name}}  ist ein Syntax-Fehler!
      Der Inhalt einer Variablen (oder positionaler Parameter) muß selbst
      ein gültiger Variablenname sein, mit dem wiederum zugegriffen wird,
      und so weiter.
      Nichtexistenz von Variablen führt zu Fehlermeldungen, mit Ausnahme
      des letzten, am tiefsten verschachtelten Namens.
      Diese Funktionalität erspart die Verwendung des eval-Kommandos,
      das zwar universeller jedoch viel umständlicher ist.
           #  a=b b=c c=ddd
           #  echo ${{{a}
           ddd
           #  echo ${{{#a}
           3
           #
      Innerhalb von Funktionen kann beispielsweise ${{3} verwendet
      werden, falls beim Aufruf als drittes Argument ein gültiger
      globaler Variablenname angegeben wurde:   funktion 24 3 qval


      Die folgenden Variablen werden von der Shell automatisch gesetzt:

      $*                   Ersetzt alle positionalen Parameter ab $1,
                           getrennt durch ein Feld-Trenn-Zeichen.
      $@                   dito - Unterschied durch Maskierung "$@".

      $#                   Anzahl der positionalen Parameter ab $1.
      $-                   Optionen vom Shell-Aufruf oder set-Kommando.
      $?                   Exit-Code des letzten ausgeführten Kommandos.
      $:                   Kommandonummer, für Prompt-Ausgabe.
      $.                   Offset der Kommandos conv, cmpv, list, (-Z-)
                                                catv, expr, readmv
      $/  $]               Anzahl expandierte Dateinamen (?*[!])  (-Z-)
                           (siehe set -f)
      $,  $}               Anzahl Argumente hinter Kommando-Namen (-Z-)
      $%                   Das aktuelle Maskierzeichen: % oder \  (-Z-)
      $$                   UNIX: Prozeßnummer der Shell
      $!                   UNIX: Prozeßnummer Hintergrund-Kdo

      $PWD                 Aktuelles Directory (pwd- u. cd-Kommando).
      $OLDPWD              Vorheriges Directory (cd-Kommando).
                           Diese beiden Variablen werden bei Shell-Start
                           und durch das bish-cd-Kommando gesetzt.
      $RANDOM              Liefert eine Zufallszahl.
                           Eine Zuweisung setzt die Zufallssequenz, was
                           jedoch nicht notwendig ist, weil automatisch.
                           (Siehe unten Gleitkomma-Arithmetik: random())
      $SECONDS             Liefert die Sekunden seit Shell-Aufruf.
                           Nach einer Zuweisung werden die Sekunden auf
                           diesen Wert addiert.
      $__ARGS__            Siehe for-Schleife.                    (-Z-)
      $__VLIM__            Wird gesetzt bei jeder Reorganisation  (-Z-)
                           eines Variablenspeichers:
                                "Anzahl   Summe der    Summe der
                                 Reorga=  gewonnenen   gewonnenen
                                 nisat.   Variablen    Bytes"
                           Siehe oben.
      $__MEMn__            Anzahl der realloc()-Aufrufe.          (-Z-)
                           Die initialen calloc() und malloc()
                           werden nicht gezählt.
      $__MEM__             Speicher-Parameter. Siehe ganz oben.   (-Z-)

      Durch aufeinanderfolgendes Lesen von $. (Offset, s.o.) können mehrere
      verschiedene Werte gelesen werden. Gültige Werte werden jedoch nur
      erlangt, wenn die jeweilige Definition beim betreffenden Kommando
      beachtet wird (s.insb. expr(K)).
      Die betreffenden Kommandos setzen $. nach erfolgreicher Arbeit auf
      mindestens einen gültigen Wert. Ein eventueller Wert von -1 wäre
      ungültig. Werte können auch undefiniert sein, da die meisten der
      in Frage kommenden Kommandos nur einen Wert setzen.
      Shell-Option -O ist zu beachten!

      Die folgenden Variablen werden von der Shell benutzt:

           IFS            Interne Feld-Trenn-Zeichen.
                          Standard ist SP-TAB-(CR-)NL.
                          Das erste Zeichen wird benutzt, um Argumente
                          voneinander zu trennen, z.B. bei "$*".
           PS1            Primärer Prompt-String. Siehe unten.
           PS2            Sekundärer Prompt-String. Siehe unten.
           $:             Kommandonummer, für Prompt-Ausgabe.

      Für das Setzen von IFS gilt eine Besonderheit:  IFS=' %9%13%10%0'
      Es können Dezimalzahlen wie vorstehend gezeigt eingebracht werden.
      Wertebereich 0..255; aus '%%' (\\) wird nicht '%' (\).
      Deshalb wird aus '%%0' '%\0', nicht aber '%0'.
      Die bish kann die binäre Null (\0) als Trennzeichen verwenden!  (-Z-)
      Es sollte nicht davon ausgegangen werden, daß an wirklich allen
      Stellen mit allen denkbaren Kombinationen 0-getrennt werden kann.
      Getestet wurden bisher 'for A in $B' und '.. | read A B C'.

      bish berücksichtigt folgende Umgebungsvariablen (Environment):
      (Setzen nach Shell-Start wird bezüglich des neuen Inhalts ignoriert.)

           PATH           Suchpfade für auszuführende Kommandos.
           CDPATH         Argument-Suchpfade für das cd-Kommando.
           HOME           Standard-Directory für das cd-Kommando,
                          für autoexec.bish, history.bish.
                          Der interne Home-Wert ist anfangs '\'.

           Die drei vorstehenden Variablen werden beim Start im Environment
           gesucht, und nochmals nach Abarbeitung von autoexec.bish, ob sie
           jetzt als Shell-Variablen vorliegen, mit ggf. neuem Inhalt.

           BISHTEMP, TEMP, TMP, TEMPDIR und TMPDIR
                          in der angegebenen Reihenfolge, zur Angabe
                          eines Verzeichnisses für temporäre Dateien.
                          Standardverzeichnis ist das aktuelle Verzeichnis.
           BISHAUTOR      Um die Autoren-Meldung zu unterdrücken:
                          BISHAUTOR=H.Schellong,Vlotho
                          export BISHAUTOR
           BISHPROGRAM    Um die FreeLizenz-Meldung zu unterdrücken:
                          BISHPROGRAM=FreeLizenz_Software_von_Helmut_Schellong
                          export BISHPROGRAM
                          (BISHAUTOR muß hierfür auch gesetzt sein.)
           setenv  BISHAUTOR     H.Schellong,Vlotho
           setenv  BISHPROGRAM   FreeLizenz_Software_von_Helmut_Schellong
           Der Autor selbst macht es wie vorstehend, in der tcsh.
           Unter Windows geht das auch, dort wo PATH gesetzt wird.


    Spezielle Substitutionen mit Variablen
      Einsetzung der Inhaltslänge einer Variablen oder eines Parameters:
           ${#name}
           ${#digit...}
      Einsetzung der Speichergröße einer Variablen:
           ${:name}
      Einsetzung der Speicheradresse einer Variablen:
           ${@name}          (als Info)
      Entweder-Oder-Substitutionen:
           ${name:-wort}     ${digit...:-wort}
           ${name:+wort}     ${digit...:+wort}
           ${name:=wort}
           :-     Falls 'name' gesetzt und nicht leer ist, wird sein Inhalt
                  eingesetzt, andernfalls 'wort'.
           :+     Falls 'name' gesetzt und nicht leer ist, wird 'wort'
                  eingesetzt, andernfalls nichts.
           :=     Eingesetzt wird der name-Inhalt.
                  Falls 'name' ungesetzt oder leer ist, wird 'wort'
                  zuvor zugewiesen.
                  Positionale Parameter können hier nicht gesetzt werden!
           Bei fehlendem ':' wird 'name' nur auf gesetzt/ungesetzt geprüft.
           'wort' muß ein geschlossener Ausdruck sein, ohne unmaskierte
           Trennzeichen!
           Diese Syntax ist verschachtelbar:   ${a:-A${b:-$ab' '$c}B}C

           Kommando 'pwd' wird nur ausgeführt, wenn 'dir' ungesetzt oder
           leer ist:   ${dir:-`pwd`}
           Falls die Einsetzung nicht benötigt wird, kann das Leer-Kommando ':'
           folgendermaßen verwendet werden:
                :  ${name:=wort} ${name:=wort} ...

      Unterschiede zwischen ${#name} und ${:name} ergeben sich, wenn ein
      Variableninhalt durch Setzen auf einen kleineren Inhalt verkürzt wird.
      Die Speichergröße wird dadurch nicht verändert. (siehe catv)
      Die Form ${@ ist nicht mit {{ oder mehr { möglich.
      Durch die Kommandos 'set :[zahl] name...' und 'local : ...' kann die
      Länge ${#name} beliebig gesetzt werden, bis maximal ${:name}.
      Die Länge ${#name} ist einfach nur eine Zahl, die die derzeitige
      Ausgabelänge einer Variablen anzeigt. Mit dem _Inhalt_ einer Variablen
      bis zum Ende ${:name} hat dieser Wert nichts zu tun.
      Die Länge ${#name} wird beispielsweise berücksichtigt von:
           echo $name  ;  catv name
           readmv  ;  writemv
           findccc  ;  findcs
      Die Länge ${:name} wird hier als Endanschlag beachtet.
      Mitunter wird auch eine Vergrößerung über ${:name} hinaus vorgenommen.
      Die Kommandos  set, catv  können das beispielsweise.


    Array-Variablen
      Die  bish  enthält Einrichtungen zum Umgang mit Arrays, mit denen
      ungewöhnlich vielfältig und leistungsfähig operiert werden kann.  (-Z-)

      Außerhalb von arithmetischen Ausdrücken:
           Zuweisungen:
                         A[index]=wert  [ B[index]=wert ... ]
                         A["  index "]=wert
                         "A[  index ]"=wert
                         Aindex=wert

                         A[123]=wert
                         A[name]=wert
                         A[$name]=wert
                         A[$((...))]=wert
                         A$name=wert
                         A$name$name=wert
                         A$((...))=wert
                         A[a[3]]=wert
                         A[a[name]]=wert

                         array [von [bis]] A [ wert ... ]
                         set -A name [ wert0 wert1 ... ]
                         typeset -i[base]  Aindex=wert ...
           Lesen:
                         echo ${A[123]} "$A[123]" $Aindex
                         echo ${A[a[ i ] ]} "$A[ a[ i ] ]"

                         array name=A index
                         array name=A 123
                         array name=A name
                         array name=A $name
                         array name=A $((...))

           Wie man sieht, ist hier fast alles erdenkliche möglich,
           beispielsweise indirekte Indexnamen.
           Als Index sind eine Konstante oder ein Variablenname gültig.
           Wie der Index zustandekommt, ist egal.
           Wichtig zu wissen ist, daß beispielsweise bei
           a[11]=22  eine Variable namens 'a11' gesetzt wird.
           Das Zeichen '[' ist beim ERSTEN Argument kein Wildcard!
           Verschachtelte Substitution  ${A[$a]}, $A[$a]  ist bei diesen
           Lesevarianten nicht möglich!

      Innerhalb von arithmetischen Ausdrücken:
           Hier gibt es die Erweiterung, daß innerhalb der Index-Klammern
           unmittelbar ein arithmetischer Ausdruck verarbeitet wird!
           Dies jedoch nur, wenn nach der öffnenden Klammer ([)
           KEIN Digit und KEIN Buchstabe steht, sondern beispielsweise
           ein Leerzeichen:   array[ arithm_ausdruck ]
           Dazu wird der Arithmetik-Modul rekursiv aufgerufen.
           Andernfalls wird derjenige schnellere Index-Leser aufgerufen,
           der auch außerhalb von arithm. Ausdrücken arbeitet.
           Falsch :  a[10+3]
           Richtig:  a[ 10+3], a[13], a[i], a[ a*b+1 ]
           Das Semikolon ist innerhalb [] nicht erlaubt, aber das Komma.
           (Siehe unten:  'Operatoren')

      Binäre und sonstige Array-Formen:
           mit tausenden Elementen und die nur unter einem einzigen Namen
           bekannt sind, können mit den Kommandos
                catv, base, prints, cut, ...
           erzeugt und bearbeitet werden!
      Das Kommando  eval  ist für indirekte Zugriffe allgemein nennenswert.



    Shell-Variablen und Speicher
      Die Variablen werden folgendermaßen im Speicher angelegt:
           name0inhalt0
      Nach  set acc:,10  sieht das so aus:
           acc0,,,,,,,,,,0
      wenn die Variable neu angelegt wurde.
      Die abschließenden 0-Bytes werden pauschal angefügt, obwohl die
      Kontrollstruktur drei Längenwerte festhält:  l = ln + li
      Wert li kann kleiner werden, während l und ln unverändert bleiben.
           set a:.100          # mit 100 Punkten füllen
           echo ${#a} ${:a}
           100 100
           set a:-50           # mit 50 Minusz. füllen
           echo ${#a} ${:a}
           50 100
           catv a /%n
           --------------------------------------------------
           catv /qq =60,0,a    # auf Offset=60 0 Byte schreiben
           echo ${#a} ${:a}
           60 100
           catv a /%n
           --------------------------------------------------.........
           base -b a +10
           45 45 45 45 45 ................. 45 45 45 45 45
           45 45 0 46 46 46 46 46 46 46 46 46
      Durch catv wurden also 60 Zeichen ausgegeben, mit der unsichtbaren 0
      nach dem letzten '-' und vor dem ersten '.'.
           a=rrrrrrrrrr
           echo ${#a} ${:a} $a ${@a}
           10 100 rrrrrrrrrr 34372645778
      Es ist erkennbar, daß die Speichergröße von Variablen ${:name} nie
      kleiner wird. Das ist nur möglich durch Löschen (unset) und
      Wiederanlegen. Zur Orientierung und Verhaltensforschung liefert ${@name}
      die Adresse eines Variableninhalts.
           catv /qq =60,1,a:
           echo ${#a} ${:a}
           61 100
           catv a /%n
           rrrrrrrrrr---------------------------------------.........q
           base -b a +10
           114 114 114 114 114 114 114 114 114 114 0 45 45 ........
           45 45 0 46 46 46 46 46 46 46 46 46 113
      Das Kommando  catv  allein kann in den gesamten Bereich einer Variablen
      schreiben und kann ihn auch lesen. Eine Null wird nur hinter der letzten
      Schreibposition angefügt, wenn die Syntax 'name:' verwendet wird und
      zuvor mindestens ein Byte geschrieben wurde. Das ermöglicht beliebiges
      Komponieren von Byte-Folgen.
      Die Kommandos  set  und  local  können in weiten Grenzen initialisierte
      Variableninhalte erzeugen. Sie sind die Speicherbeschaffer.



    Zwischenraum-Interpretation
      Nach Parameter- und Kommando-Substitution wird das Resultat gemäß
      dem Inhalt der Variablen IFS aufgeteilt und so Argumente gebildet.
      Man beachte hier die Maskierungsmöglichkeiten, die eine explizite
      (andersartige) Argumentbildung ermöglichen. (siehe unten.)
      Explizite Null-Argumente per  "" und ''  werden erhalten, implizite
      jedoch nicht. Zwischen $HAND und "$HAND" besteht also ein Unterschied,
      wenn HAND den Null-String enthält.
      Mindestens ein Leer-Argument kann man erzwingen durch:
           "$HAND"  oder  ""$HAND  oder  $HAND''  oder
           ""` kommando `    (wenn kommando nichts ausgibt.)
      Bei Fehlermeldung sollte zuerst überlegt werden, ob diese durch
      'kein Argument' ausgelöst werden konnte.


    Dateinamen-Expansion
      Nach Substitution wird jedes Kommando-Wort nach unmaskierten
      Zeichen  ? * [  durchsucht, sofern die Option -f nicht gesetzt ist.
      Bei Arg0 wird [ nicht bewertet, wenn es eine Konstante ist.
      Zwei oder mehr entstehende Kommandonamen (Arg0) sind ein Fehler.
      (siehe regexp®)
      Ein solches Wort wird durch eine Liste von passenden Dateinamen
      ersetzt. Paßt kein Dateiname, bleibt das Wort unverändert.
      Die Dateinamen werden zum Vergleich so:  NNNN.EEE  oder so:  NNNN
      angeliefert, deshalb würde  NNNN.  nie gefunden (Punkt!).
      Achtung! Ein vorhandener Punkt wird als normales Zeichen gewertet.
      *.*  würde daher zu sämtlichen Dateinamen passen, die eine Erweiterung
      haben. Ein einzelner Stern * paßt zu sämtlichen Dateinamen.
      Beispiele:
           echo  c:\windows\*\pscrpt.drv
                  Sucht in allen Unterverzeichnissen in \windows
                  nach der angegebenen Datei und zeigt sie per echo-Kommando.
           \???\??\??\*txt
                  Alle Namen, die mit txt enden, mit oder ohne Punkt davor,
                  in Verzeichnissen mit 2 Zeichen (Erweiterung ausgeschlossen),
                  die in Verzeichnissen mit 2 Zeichen sind, die wiederum
                  in Verzeichnissen mit 3 Zeichen sind.
                  Z.B.:   \K.Z\AB\BC\RGTXT
           ?*erf?*.?[i-o]*
                  Alle Namen, die 'erf' enthalten, und davor und danach
                  -bis zur Erweiterung- mindestens ein beliebiges Zeichen,
                  und die eine Erweiterung haben aus mindestens 2 Zeichen,
                  wobei das zweite ein Buchstabe von I bis O sein muß.
                  Z.B.:   kerfi.sig   merfolg.ak   merfl.roh
           echo \sys\*\?*.[a-h]
                  \SYS\CFG\INIT.D \SYS\CFG\CF.D \SYS\CFG\NODE.D \SYS\CFG\SD
                  EVICE.D \SYS\CFG\PACK.D \SYS\CFG\SFSYS.D \SYS\CFG\MFSYS.D 
                  \SYS\CFG\RC.D \SYS\CFG\SD.D
                  Alle Namen, die in beliebigen Unterverzeichnissen des
                  Verzeichnisses \sys stehen und mindestens ein Zeichen vor
                  einem Punkt haben und nach dem Punkt als letztes Zeichen
                  eines der Zeichen A...H haben.
           Bei solchen Ausdrücken kann es natürlich mitunter vorkommen, daß
           hunderte passende Pfade gefunden werden und der Argumentspeicher
           dafür nicht mehr ausreicht.
           Die Namen ganz rechts können grundsätzlich auch Verzeichnisse sein!

      Bei Maskierung der Spezialzeichen mit Hilfe von % (s.u.) wird % nicht
      entfernt, damit man letztlich z.B. nach Dateien  ??K_VES, ??L_VES, ...
      suchen kann:  Suchmuster:  %?%??_VES
      Man sollte jedoch solche Dateinamen vermeiden und am besten per
      "?*[" oder '?*[' maskieren; die Maskierung per % macht auch nur Sinn,
      wenn man anschließend tatsächlich Dateinamen suchen will.
      (Siehe auch oben:  $] )


    Maskierung
      Die Spezialbedeutung von Zeichen kann durch verschiedene Formen
      der Maskierung  ( % \   '...'   "..." )  aufgehoben werden.

      % \  Das Prozentzeichen % oder der Backslash \ (per Option -B) ist
           das generelle Maskierzeichen.
           Es hebt jede aktuelle Spezialbedeutung auf und wird danach entfernt.
           Es maskiert sich auch selbst.
           Wenn es vor einem Zeichen steht, das gar keine (aktuelle) Spezial=
           bedeutung hat, wird es jedoch nicht entfernt!
           Man beachte, daß  %c  (c) für die Shell keine Spezialbedeutung hat,
           aber wohl für das echo- und print-Kommando.
           Die Zeichenfolge  %NL  wird ignoriert (Zeilenverlängerung).
           Bei Maskierung der Spezialzeichen für die Dateinamen-Expansion
           (?*[, s.o.)  wird % ausnahmsweise nicht entfernt!

      '..' Zwischen zwei Apostroph ' sind alle Zeichen maskiert;
           Nach dem ersten ' werden zwei Apostroph ('') durch ein ' ersetzt.
           'wer|seq''&&%%'  resultiert zu  wer|seq'&&%%   (-Z-).
           Oder:  Nach einem ersten ' hat nur noch ' eine Spezialbedeutung.

      ".." Nach einem ersten " haben nur  $ ` % und "  Spezialbedeutung.
           $* und $@ sind unmaskiert identisch.
           Jedoch  "$*"  entspricht  "$1_$2_$3_...", wobei _ das erste Zeichen
           in IFS ist (i.a. SP), und  "$@"  entspricht  "$1" "$2" ...

      Beispiel:
           ZVSCH=Zeilenvorschübe
           echo "%r%n
              Bis jetzt gelten 2(!) $ZVSCH, gefolgt von 3 Leerz.
           "
           Nach dem Satz folgen 2 Zeilenvorschübe.


    A r i t h m e t i s c h e   B e r e c h n u n g e n
      Arithmetische Ausdrücke folgen den Regeln der Programmiersprache C,
      sind aber nicht vollkommen damit identisch (-Z-).
      Drei Syntax-Formen:  let ".." '..' ...  und  ((..))  und  $((..))
      Abschließend wird Gleitkomma-Arithmetik beschrieben.
      Operatoren, von oben nach unten mit fallendem Rang:
           ()  []  {}
           **  ::
           !  ~  ++  --  +  -  *  ::  #          unär
           *  /  %
           +  -
           <<  >>
           <  <=  >  >=
           ==  !=
           &
           ^
           |
           &&
           ^^
           ||
           ?:
           =  +=  -=  *=  /=  %=  &=  ^=  |=  <<=  >>=
           ,
           ;
      Komma und Semikolon trennen (Teil-)Ausdrücke. (-Z-)
      Der unäre * berechnet das Quadrat.  a^^b  entspricht  !a^!b .
      Der Ausdruck  x**e  entspricht  x^e .
      Der Ausdruck  x::n  entspricht  x^(1/n), also der n-ten Wurzel.
      Der Ausdruck   ::x  entspricht  sqrt(x).
      Mittels  #z  wird der Wert des Bytes nach # generiert.
      Mehrfachzuweisungen und  ++name --name  (-Z-) sind möglich.
      Operator 'cond?true:false' ist vorhanden (-Z-), der zusätzlich
      auch Referenzen (wie bei C++) verarbeitet!
      array[ arithm_ausdruck], array[name_oder_zahl]:  siehe oben.
      Auf Variablen kann/sollte ohne das Dollar-Zeichen zugegriffen werden.
      Zur Berechnung kann das Kommando let (s.u.) verwendet werden und die
      symbolische Syntax  ((ausdruck))  und  $((ausdruck)) .
         Dieser Mechanismus überflügelt (bei Arithmetik)
         das alte test-Kommando.
      Datentyp 64 Bit oder 32 Bit breit (siehe typeset -S).
      Zwischenraumzeichen und NL können beliebig eingefügt werden.
      Positionale Parameter ($0,$1,...) können nicht verarbeitet werden!
      ---
      Integer Zahlenkonstanten sind standardmäßig dezimal.
      Es sind jedoch Konstanten mit allen Basen von 2 bis 36 und 256
      verarbeitbar!  Dazu muß  'base#number'  angegeben werden.
      Die Ausgabebasis für $((...)) kann man so:  $((base#, ...))  setzen,(-Z-)
      wobei dies temporär die globale Basis überschreibt, die mittels
      'typeset -sbase' (s.u.) gesetzt werden kann.
      Ausdruckbasis 256  $((256#, ...))  funktioniert allerdings nicht!
      Beispiel:   V44=44
                  echo $(( W=---23+$V44*
                               -(2+-5);1111
                        ))
                  echo $W
                  ((D={[(11+2)*3-6]*4-33}*5))
                  echo $D
                  let "A=B=C=W*6-*2*8;W=*W" "D={[(11+2)*3-6]*4-33}*5"
                  echo $A $B $C $W $D

      Ausgabe:    1111
                  109
                  495
                  622 622 622 11881 495
      Man beachte, daß das erste echo-Kommando nur '1111' ausgibt!
      Die Argumente zu  let  werden zuerst von der Shell interpretiert
      und nachfolgend noch einmal vom Arithmetik-Modul (s. eval, trap)!
      Daher sind HIER positionale Parameter möglich!
                  AUSDR='X=3*7'
                  let "$AUSDR+$2"
      Möglich sind auch:
                  echo aaa((A=222+111))bbb${A}ccc  -->  aaabbb333ccc
                  ((bs=123+9))echo $bs             -->  132
      sofern ( unmaskiert ist.
      '$((' ist hier NICHT maskiert!:  "...$((...))..."
      Es wird nicht nach Nur-Environment-Variablen gesucht.
      Folgende Ausdrücke sind durchaus möglich:
                  echo $(( l=8 ; l+(++l+=5) )) $l      --> 22 14
                  echo $(( l=8 ;  l+++l+=5  )) $l      --> 22 22
      Letzterer wird verarbeitet, l bekommt aber eine weitere Zuweisung.
      NACHgestellte ++ -- werden nicht(!) als Inkrement/Dekrement verarbeitet.
                  (( 16#ffff<256#zzzz && 555<=666 )) && echo TRUE
      Die Formen 'let ...' und  ((...))  haben einen Exit-Code!
                  $(( a=b= c!=48 ? 11 : 22, 88 ))
      Zuweisung in Abhängigkeit einer Bedingung. Ausgabewert ist 88.
                  (( c>=33 ? a : b = 66 ))
      In Abhängigkeit wird a oder b auf 66 gesetzt!
      Klammern beim ternären Operator versperren jedoch solche Referenzen!
      Diese Konstruktion kann auch mitten in einer Mehrfachzuweisung stehen,
      und Verschachtelungen (mit Klammern!) sind auch möglich.

      G l e i t k o m m a - A r i t h m e t i k

      Eine Gleitkommaverarbeitung erfolgt automatisch, einfach durch Angabe
      einer Gleitkomma-Notation mit Punkt '.' und/oder Exponentzeichen 'e|E'.
      Dabei muß vor und hinter dem Dezimalpunkt eine Ziffer stehen.
      Gültige Notationen:  2.3 +2.3  -2.3  23.45e4  2.3e+4  2.3e-4  2e4  -2e4

      Falls eine Konversion zu 2345 vorkommt, wird '.0' angehängt, so daß
      eine Ausgabe von 2345.0 entsteht, um eine Weiterführung der
      Gleitkommazahl-Eigenschaft zu gewährleisten.
      Funktionen verlangen bei Integer-Argumenten den Integer-Typ.
      Es wäre falsch, bei einer Angabe factorial(3.4) einfach implizit
      zu factorial(3) oder factorial(4) zu verändern.

      let "functions()"
        f= acosh(f)          f= acos(f)           i= arith_()
        f= asinh(f)          f= asin(f)           f= atan2(f,f)
        f= atanh(f)          f= atan(f)           f= avogadro()
        f= boltzmann()       f= c()               f= cart_polar(f,f,$)
        f= cbrt(f)           f= ceil(f)           i= constants()
        f= copysign(f,f)     f= cosh(f)           f= cos(f)
        i= dec_hour(f,$,$)   f= degtorad(f)       f= e()
        f= earthacc()        f= ec()              f= eps0()
        f= epsilon()         f= erfc(f)           f= erf(f)
        f= exp2(f)           f= exp(f)            f= expm1(f)
        f= fabs(f)           f= factorial(i)      f= faraday()
        f= fdim(f,f)         f= floor(f)          f= fma(f,f,f)
        f= fmax(f,f)         f= fmin(f,f)         f= fmod(f,f)
        i= formula_yx($,$)   f= frexp(f,$)        i= functions()
        i= getround()        f= goldenratio()     f= gravity()
        i= hash($,i,i)       f= hour_m_s(i,i,i)   f= hypot(f,f)
        f= klitzing()        f= ldexp(f,i)        f= lgamma(f)
        i= llrint(f)         i= llround(f)        f= log10(f)
        f= log1p(f)          f= log2(f)           f= logb(f)
        f= log(f)            f= modf(f,$)         f= mue0()
        f= nan()             f= nchoosek(i,i)     f= nearbyint(f)
        f= nextafter(f,f)    f= nexttoward(f,f)   f= pi()
        f= pi2()             f= planck()          f= plancke()
        f= polar_cart(f,f,$) f= pow(f,f)          f= quaequ3p(f,f,f)
        f= quaequ3m(f,f,f)   f= quaequ2p(f,f)     f= quaequ2m(f,f)
        f= radtodeg(f)       i= random(i)         f= remainder(f,f)
        f= remquo(f,f,$)     f= reciprocal(f)     f= rint(f)
        f= root(f,f)         f= round(f)          f= rpar2(f,f)
        f= rpar3(f,f,f)      f= scalbln(f,i)      i= setround(i)
        f= sinh(f)           f= sin(f)            f= sqrt2()
        f= sqrt3()           f= sqrt(f)           f= tanh(f)
        f= tan(f)            f= tgamma(f)         f= trunc(f)
        f= z0()

      f: Float, i: Integer, $: Variablenname <-> Wert
      Als Funktionsargument dürfen nur ein Variablenname oder eine Konstante
      angegeben werden - kein größerer Ausdruck.
      Die meisten Funktionen entsprechen dem C-Standard C99.
      Beschreibungen sind auch in kostenlosen Drafts des Standard vorhanden:
      http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1570.pdf

      Beispiel-Skript, welches bish-Gleitkomma intensiv benutzt:
      http://www.schellong.de/htm/rpar.bish.html

      Die Funktionen 'rpar2' und 'rpar3' berechnen den Gesamtwiderstand von
      zwei bzw. drei parallel geschalteten Widerständen:
                                                        1
           a * b            a * b * c        -----------------------
          -------       -----------------      1     1     1
           a + b         a*b + a*c + b*c      --- + --- + --- + ...
                                               a     b     c
      Das ist nicht auf elektrische Widerstände beschränkt.
      Die Formel gilt z.B. auch für in Reihe geschaltete Kondensatoren.
      Die Funktion 'nchoosek' wird auch 'n über k' und Binomial-Koeffizient
      genannt:      n!
               -----------    ; nchoosek(49,6) = 13983816
                k! (n-k)!
      Die Darstellung  x!  ist die 'Fakultät von x'.
      Siehe oben factorial(i); Maximum von i ist 1754 bei 80-Bit-Float.
      Die Maxima bei 'nchoosek' werden davon nicht berührt, da hier die
      vorstehende Formel in viele Schritte zerlegt wird.

      Die Funktion  z= random(i)  liefert Integer-Zufallszahlen und
      implementiert den Algorithmus 'Spritz', den Nachfolger des 'arc4/RC4'.
      Kryptographisch sichere, hochqualitative Zufallszahlen werden generiert.
      Das Funktionsargument i hat zwei besondere Werte und einen Wertbereich:
         0        Standard: z = 0..2^32-1
         1        Neue Sequenz setzen (return=0).
         2..n     Max-Wert: z = 0..n-1; n<=2^63-1 (2^64-1)
      Da der Arithmetik-Modul bei Integer und Gleitkomma vorzeichenbehaftet
      arbeitet, kann der höchste Wert nur durch random(-1) angegeben werden,
      wobei ein Teil der Werte von  z  negativ dargestellt werden.
      Max-Wert: random(2) .. random(9223372036854775807).
      Die Funktion random() benötigt keinen seed-Wert zum Ändern der Sequenz
      der Zufallszahlen. Sie initialisiert sich selbst mit sich ständig
      ändernden Dateninhalten. Sie initialisiert sich ebenfalls nach einer
      bestimmten Menge an ausgegebenen Zufallszahlen periodisch neu.
      Bei 0 = Standard gibt es keine Reduzierung der Werte;
      Die Deckelung des Wertes der Zufallszahlen erfolgt nicht einfach
      nur durch eine Restwertdivision, sondern vermeidet einseitige Werte.
      (Operator ^ ist in der Arithmetik kein Exponent-Operator!)
      (Siehe oben den Mechanismus '$RANDOM'.)

      Die Funktion  i= hash(name,max,var)  liefert Hash-Werte, die als
      Zugriffsindex geeignet und abhängig von den in 'name' enthaltenen
      Daten (gewöhnlich Zeichenketten) sind.
         name     Variableninhalt soll eine Byte-Folge sein.
                  Byte-Werte von 0 dürfen enthalten sein.
         max      i = max-1 als Maximum; max = 2..2^32-1;
                  Bei max<2 wird die Begrenzung (i mod max) abgeschaltet
                  und i kann Werte 0..2^63-1 annehmen.
         var      Auswahl des Algorithmus; Wertebereich 0..6
      Bei der Auswahl 'var' gibt es drei Algorithmen: 0|1,2,3|4,5,6.
      Die beiden letzten Algorithmen können mittels je drei verschiedener
      Aufrufzahlen unterschiedlich gesteuert werden:
         1|4      Initialisierung bei jedem Aufruf (wie bei 0).
         2|5      Initialisierung durch vorherigen Hash-Wert.
         3|6      Initialisierung durch oberen Teil von 'var'.
      Der obere Teil von 'var' beginnt ab dem fünften Bit.
      Die unteren vier Bit (0..15) müssen die Auswahl enthalten.
      Bei 2|5 beträgt der vorherige Hash-Wert nach Shell-Start 0.
      Falls bei 2|5 der obere Teil von 'var' größer 0 ist, wird der
      initialisierende Wert (normalerweise der vorherige Hash)
      auf 0 gesetzt.
      In Verbindung mit 'Hashes' sind Kollisionen ein wichtiges Thema:
      Wenn unterschiedliche Daten gleiche Hash-Werte ergeben!
      Beispiel 1:  hash(zeichen,100,0)
         abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ
         (a b c d e f ...;  ab cd ef gh ...;  abcd efgh ijkl ...)
         0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
         21 22 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80
         81 82 83 84 85 86 87 88 89 90 97 98 99.
         6 8 10 12 14 18 20 22 24 40 42 44 46 50 52 54 56 58 74
         76 78 80 84 86 88 90.
         12 14 18 36 42 54 60 64 66 84 88 90 94.
      Es sind Kollisionen vorhanden, allerdings wurde für die 52|26|13
      Zeichenketten ein enger Wertebereich von 0..99 erzwungen.
      Innerhalb jeweils einer Länge (1|2|4) gibt es keine Kollision.
      Beispiel 2:  hash(zeichen,58,0)
         abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ
         0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
         21 22 23 24 25 26 27 28 29 30 31 32 39 40 41 42 43 44
         45 46 47 48 49 50 51 52 53 54 55 56 57
      Beim Verhältnis 58:52 noch keine Kollisionen!
      Die fehlenden 58-52=6 Werte sind 33..38.

      Die Funktionen 'quaequ[23][pm]' berechnen quadratische Gleichungen.
      Die Argumente sind von links nach rechts  a b c  und  p q.
      Das Vorzeichen vor der Wurzel wird durch  p  und  m  bestimmt.

      Die Funktion 'm=getround()' bzw. 'r=setround(m)' liefert den aktuellen
      Rundungsmodus bzw. setzt diesen:
         Rundung in Richtung 0.0         :  0
         Rundung zur nächsten ganzen Zahl:  1
         Rundung in Richtung +Unendlich  :  2
         Rundung in Richtung -Unendlich  :  3
      Bei 'setround' ist der Rückgabewert r=1|0 der Okay|Fehlschlag-Wert.
      Der Exit-Wert außerhalb der Arithmetik ist dazu e=0|1.
      Folglich ist möglich:  let "setround(0)" && echo "Modus 0 gesetzt."
      Der Modus '1' ist die häufigste Voreinstellung.
      Die Funktionen 'rint', 'nearbyint' und 'llrint' verwenden den
      aktuell eingestellten Rundungsmodus.

      Die Funktionen   x= polar_cart(r,phi,y)
                       r= cart_polar(x,y,phi)
      wandeln polare in kartesische Koordinaten um und umgekehrt.
      Es ist zu beachten, daß das dritte Argument ($) das zweite Ziel für
      einen Resultatwert ist.

      Die Funktionen   h= dec_hour(dh,m,s)
                      dh= hour_m_s( h,m,s)
      wandeln Dezimalstunden (dh) in Stunde, Minute, Sekunde um und umgekehrt.
      Bei dec_hour() sind die Argumente  m,s  zwei Ziele ($) für Resultatwerte.
      Beispiel:  100.01 = hour_m_s(0,0,360036)


      Die Funktion  count= formula_yx(vars,formel)  ist eine Besonderheit.
      Sie errechnet in Formeln (mehrere) X, abhängig von Y, anstatt umgekehrt.
      Das erspart die algebraische Umstellung einer Formel.
      Weiterhin eröffnen sich verschiedene Analysemöglichkeiten.
      Die Bezeichner 'vars' und 'formel' sind Variablennamen.
      Die Variable 'vars' enthält mindestens 5 Variablennamen.
      Die Variable 'formel' enthält grundsätzlich beliebigen Shell-Code, der
      mindestens eine Formelberechnung mit Resultat Y enthalten muß.
        vars  :  Ysoll Prozent Divisor  Y Parameter_X...
        formel:  Shell-Code mit maximal 2040 Zeichen Umfang.
      Der formel-Code ruft den Arithmetik-Modul rekursiv auf.
      Alle Variablennamen sind frei wählbar.
      Deren semantische Reihenfolge ist jedoch zwingend festgelegt.
      Die Größe 'Ysoll' bezeichnet den zu erreichenden Sollwert.
      Mittels 'Prozent' werden initiale Delta-Werte errechnet.
      Diese werden zyklisch durch 'Divisor' reduziert.
      Beispiel 1:
        typeset -f ysoll=290.0 proz=3.0 div=5.0
        typeset -f y=0.0 r1=200.0 r2=200.0 r3=300.0
        typeset -i count=0
        local yc:09
        ARITH_FMT='%Lg'
        formel='let "y= 1.0 / (1.0/r1+1.0/r2+1.0/r3)" "++count"
                echo $y $r1 $r2 $r3 : $count'
        vars='ysoll proz div y r1 r2 r3'
        let "yc=formula_yx(vars,formel)"
        echo $yc : $y $r1 $r2 $r3
      Ausgabe 1:
        75.0 200.0 200.0 300.0 : 1
        75.8282 206.0 200.0 300.0 : 2
        76.6749 206.0 206.0 300.0 : 3
        ... ...
        290.004 774.752 770.0 1164.43 : 309
        289.995 774.752 770.0 1164.29 : 310
        289.993 774.704 770.0 1164.36 : 311
        4 : 289.993 774.752 770.0 1164.36
      Auffällig ist:  300/200 = 1164/772 = 1.5
        Der evolutionäre Algorithmus erhöht also die Initialwerte im gleichen
        multiplikativen Maß.
      Im Beispiel oben (Formel wie 'rpar3') können 'r3' oder 'r2 r3' beim
      Inhalt von 'vars' weggelassen werden: Ein Ysoll = 290 ist durch ein
      Weglassen von 'r2 r3' allerdings nicht mehr erreichbar, weil lediglich
      'r1' zur Änderung zur Verfügung steht!
      Denn r2||r3 = 200||300 = 120, was zur Folge hat, daß 120 nicht
      erreichbar ist, weil 'r1' dafür unendlich groß werden müßte, was
      jedoch nicht möglich ist:
      Ausgabe 2:
        119.985 929396.0 200.0 300.0 : 154915
        119.985 929396.0 200.0 300.0 : 154916
        'formula_yx(): kein Resultat!'
        -27 : 119.985 929396.0 200.0 300.0
      In Beispielen hier werden die Formelgrößen/Parameter:
        'r1 r2 r3'  bzw.  'a d l'
      verwendet. Es können in 'vars' jedoch bis zu 5000 Formelgrößen
      angegeben werden.
      Die Werte oben für 'proz' und 'div' sind als Ansatz empfehlenswert.
      Verminderung von 'proz' verursacht mehr Durchläufe, ergibt aber
      genauere Resultate.
      Der Rückgabewert 'count' beträgt in der Regel 1 bis 5.
      Er zeigt an, wie oft 'Divisor' verwendet wurde.
      Der Zeitbedarf beträgt nur etwa 0,001 Sekunden für 1000 Durchläufe!
      Beispiel 2:
        typeset -f ysoll=50.0 proz=3.0 div=5.0
        typeset -f y=0 a=1.0 d=0.1 l=100 k=0 r=0 g=0
        typeset -i count=0
        local yc:09
        ARITH_FMT='%Lg'
        formel='let "k=2.0*a/d" "r=1.0-1.0/(k*k)" "g=k*(1.0+sqrt(r))" %
                "y=0.24*l/log10(g)" "++count"
                echo $y $a $d $l : $count'
        vars='ysoll proz div y a d l'
        let "yc=formula_yx(vars,formel)"
        echo $yc : $y $a $d $l
      Ausgabe 1:
        14.9833 1.0 0.1 100.0 : 1
        14.864 1.03 0.1 100.0 : 2
        15.1082 0.97 0.1 100.0 : 3
        ... ...
        49.9997 0.28 0.168958 168.999 : 106
        50.0001 0.28 0.168959 169.0 : 107
        6 : 50.0001 0.28 0.168958 169.0
      Auffällig ist auch hier:  100/0.1 = 169/0.169 = 1000
      Ausgabe 2:
        149.833 1.0 0.1 1000.0 : 1
        148.64 1.03 0.1 1000.0 : 2
        ... ...
        50.0001 1.6144 0.04 460.0 : 77
        49.9928 1.6156 0.04 460.0 : 78
        3 : 49.9928 1.6144 0.04 460.0
      Die Größe 'l' wurde hier größer gewählt: 1000 statt 100.
      Die Initialisierung bei  typeset -f  muß nicht per Gleitpunktnotation
      erfolgen, sondern statt '0.0' ist auch '0' möglich, weil die
      Option -f (float) Gleitpunkt vorgibt.
      Kommando 'typeset' erzeugt standardmäßig lokale Variablen.
      Außerhalb von Funktionen gibt es ebenfalls eine lokale Ebene.
      Die maximale Anzahl von lokalen Variablen ist relativ gering.
      Es kann nötig sein, das Kommando 'global' zu verwenden.
      Falls eine Variable in 'vars' nicht per 'typeset -f' erzeugt wurde,
      wird sie intern von 'formula_yx()' so verändert, als ob sie per
      'typeset -f' erzeugt worden wäre.
      Siehe auch Kommandos 'localset', 'set' und 'ver l'.
        FORMYX_ERFOLG: 0.1e-6
        FORMYX_DEVDIV: 250.0e3
      Vorstehend Konfigurations-Variablen für 'formula_yx()' mit
      ihren voreingestellten Werten.
      Der Inhalt der ersten Variable (vorher - aktuell >= ERFOLG) ist
      ein Schwellenwert für eine Differenz.
      Die zweite Variable enthält einen Divisor (dev = Ysoll/DEVDIV), der
      eines von zwei Beendigungskriterien bildet.
      Ein kleinerer Wert führt zu einem früheren Beenden.


      let "constants()"
        avogadro        6.022140857e+23            [mol^-1]
        boltzmann       1.38064852e-23             [J/K]
        c               299792458                  [m/s]
        e               2.718281828459045235       [1]  Eulersche Zahl
        earthacc        9.80665                    [m/s^2]  Erdbeschleunigung
        ec              1.6021766208e-19           [C]  Elementarladung
        eps0            8.854187817620389851e-12   [As/Vm]  Elektrische Feldkon
        epsilon         1.084202172485504434e-19   [1]
        faraday         96485.3365                 [C/mol]
        goldenratio     1.618033988749894848       [1]
        gravity         6.67408e-11                [m^3/(kg s^2)]
        klitzing        25812.8074555              [Ohm]
        mue0            1.256637061435917295e-06   [N/A^2]  Magnetische Feldkon
        pi              3.141592653589793239       [1]
        pi2             6.283185307179586477       [1]
        planck          6.62607004e-34             [Js]  Wirkungsquantum
        plancke         4.135667662e-15            [eVs]  Wirkungsquantum
        sqrt2           1.414213562373095049       [1]
        sqrt3           1.732050807568877293       [1]
        z0              376.730313461772567        [Ohm]

      Die vorstehenden Service-Tabellen werden von Funktionen ausgegeben.
        let "functions()"
        let "n=constants()" ; echo $n
        echo $((functions()))
      Bei den letzteren Ausgaben wird zum Schluß '20' bzw. '96' ausgegeben.

      Kontroll-Variablen
        ARITH_FMT='%.*Lg'      Format für Print-Funktionen
        ARITH_EXP3=yes         Exponent-Darstellung 0 3 6 9 12 15 ...
        ARITH_DEG=no           Grad oder Radiant bei Trigonometrie
      Gezeigt sind die Voreinstellungen.
      Falls ein Stern * im Format angegeben wird, dann nur .* für Präzision.
      Bei .* wird LDBL_DIG (<float.h>) verwendet.
      Ohne .* kann beispielsweise  .10  direkt angegeben werden.
      'L' für 'long double' muß zwingend angegeben werden.
      Als Formatzeichen können  f e g F E G  gewählt werden.
      Das Format wird nicht geprüft, da es zu vielschichtig ist!
      Als 'Ja' wird erkannt: Y y 1 (nur das erste Zeichen), andernfalls 'Nein'.
      Die Funktionen arith_(), functions() und constants() sorgen dafür, daß
      die drei Variablen vor ihrer nächsten Verwendung neu gelesen werden.

      Für einen konvertierten Wert steht begrenzter Speicher zur Verfügung.
      Dieser reicht aus, um bei einem 128-Bit-Format (Quad-extended-precision)
      jedes eEgG-Format-Konversionsergebnis zu speichern.
      Das Format 'fF' jedoch kann prinzipiell ein mehrere Tausend Zeichen
      langes Konversionsergebnis zur Folge haben!
        ARITH_FMT='%.*Lf'
        let "a=23e27";echo $a
        bish: Arithmetischer Ausdruck: 'Konversion fehlgeschlagen'
        let "a=23e26";echo $a
        2300000000000000000067108864.000000000000000000
      Es ist vorstehend erkennbar, daß hinter der Stellenanzahl, die noch eine
      genaue Zahl repräsentiert, Ungenauigkeiten auftauchen.
      Deshalb ist es so wichtig, 'epsilon' zu verwenden.
      Zur Konversion wird die C-Funktion 'snprintf' verwendet.

      Bei den Operatoren  == != && || ^^ !  und bei logischem 'Ist nicht Null'
      wird Epsilon (LDBL_EPSILON <float.h>) verwendet.
      Siehe oben 'epsilon()' und 'epsilon'.

      Ausgaben mit technischer Exponent-Notation:
        ARITH_FMT='%.5Le' 
        let "a=123e8";echo $a
        12.3000e+09
        let "a=1.23e8";echo $a
        123.000e+06
        let "a=1.23e-8";echo $a
        12.3000e-09
      Exponent: ... mikro milli kilo Mega Giga ...

      Man kann hier das Wort 'Gleitkomma' als falsch ansehen, da hier überall
      'Gleitpunkt' dargestellt ist. Andererseits kann korrekt 'Gleitkomma'
      (im Deutschen) und 'Floating point' (im Englischen) als Begriff genannt
      werden.
      Eine Internationalisierung im Gleitkommabereich wurde nicht vorgenommen.
      Insgesamt wäre das auch letztlich unsinnig und problematisch.
      Auf der Ebene der Syntax einer Programmiersprache gibt es ohnehin keine
      Wahl von '.' oder ','. Auch Tausender-Trennzeichen gibt es nicht.
      Und die hier beschriebenen Gleitkomma-Merkmale sind ebenfalls auf der
      Ebene der Syntax der Shell-Programmiersprache befindlich.
      ---
      Eine zeichenweise Umformung kann leicht von internen bish-Kommandos
      vorgenommen werden:  conv -T., dval kval teiler ...
      Mittels 'expr' kann sowieso Alles gemacht werden.



    Eingabe/Ausgabe
      Vor der Ausführung eines Kommandos kann seine Ein- und Ausgabe mit
      einem oder mehreren speziellen Umlenkungs-Argumenten umgelenkt werden.
      Diese Argumente werden nicht an das Kommando übergeben.
      Nach Interpretation durch die Shell darf aus ``Datei'' nur ein einzelnes
      Argument geworden sein.
      Umlenkungsargumente können auch als eigenständiges Kommando abgesetzt
      werden, wirken dann global und können schrittweise oder auf einmal
      zurückgenommen werden (-Z-).
      Vor die unten angegebenen Zeichen < > können Digits als explizite
      Angabe des Datei-Handles gestellt werden.
      Implizit werden die Handles 0< oder 1> angenommen.
      Desweiteren können die Buchstaben
           b     O_BINARY-Modus
           t     O_TEXT-Modus
           e     O_EXCL - Exklusive Kreation, mit entsprechendem Exit-Kode.
           s     O_SYNC-Flag
           C     O_NOCTTY-Flag
           N     O_NDELAY(SCO)- oder O_NONBLOCK-Flag
           B     Blockmode (siehe unten) (SCO-Unix,[WinNT])
      vorangestellt werden (-Z-):
           [{b|t}esCNB][digit]{>|<}
      Standardmäßig ist BINARY eingestellt, auch für die Handles 0,1,2.
      Bei den Umlenkungsformen mit '&' haben b oder t keinen Sinn!
      Blockmode:
      Die lseek()-Funktion (siehe Kommando 'seek') wird auf
      BlockMode eingestellt und arbeitet somit nicht mit Byte-Einheiten,
      sondern mit Sektor-Einheiten (je 512 Byte).
      Auf diese Weise können Objekte bis 1 TeraByte Größe erfaßt werden.
      Dabei:  Lesen und Schreiben nur mit n=x*512 !
      bish64 (z.Z.UnixWare7) arbeitet stets im LARGEFILE-Modus.

           <Datei         Standard-Eingabe kommt aus Datei.

           >Datei         Standard-Ausgabe geht zu Datei.
                          Datei wird erzeugt oder auf Null-Größe gebracht.
                          Bei gesetzter Option -N gibt es eine Fehlermeldung,
                          wenn Datei schon existiert und Inhalt hat.

           <>Datei        Datei wird zum Lesen und Schreiben geöffnet
                          und mit Handle 0 verknüpft.
                          Datei wird erzeugt, falls sie nicht existiert,
                          und bei Existenz NICHT auf Null-Größe gesetzt.

           >|Datei        Ignoriert eine gesetzte Option -N.

           >>Datei        Standard-Ausgabe geht zu Datei.
                          Datei wird erzeugt oder es wird an bisherigen
                          Inhalt angehängt.

           << Wort        HERE-Dokument:
           <<-Wort        Handle 0 wird mit dem Text verknüpft, der nach
                          Wort folgt.
                          Der Text wird beendet durch 'Wort' falls Wort
                          ebenfalls 'Wort' lautet, oder durch EOF.
                          Bei <<- werden führende TABs entfernt.
                          Nach <<[-] hat kein Zeichen Spezialbedeutung.
                          Nicht innerhalb von $( ) oder ` ` verwenden!
                          Siehe unten.

           <&Digit        Die Standard-Eingabe (Handle 0) wird mit Handle
                          Digit verknüpft.

           >&Digit        Die Standard-Ausgabe (Handle 1) wird mit Handle
                          Digit verknüpft.

           <&-            Standard-Eingabe wird geschlossen.
                          Als Argument: Verkn. mit /dev/null
                          Als Kommando: close(); >< nicht anwendbar.
           >&-            Standard-Ausgabe wird geschlossen.
                          Als Argument: Verkn. mit /dev/null
                          Als Kommando: close(); >< nicht anwendbar.

           >&t0           ioctl(fd, TIOCNOTTY, 0)
           >&t1           ioctl(fd, TIOCNOTTY, 1)
                          Assoziation als Controlling Terminal
                          (<> werden ignoriert; keine Rückverkn.)
           >&c0           fcntl(fd, F_SETFD, 0)
           >&c1           fcntl(fd, F_SETFD, 1)
                          Close on exec Flag
                          (<> werden ignoriert; keine Rückverkn.)

           ><             Nimmt die letzte vorgenommene globale
                          Umlenkung zurück.  (-Z-)
           ><<<           Nimmt drei globale Umlenkungen zurück.
                          Die Anzahl der < ist hier entscheidend.  (-Z-)

           Globale Umlenkungen entsprechen den System-Calls 'open()'
           und 'close()', mit zusätzlicher Verknüpfung mit einer ganz
           bestimmten Dateinummer (handle) und späterer Rückverknüpfung
           und Wiederherstellung des ursprünglich mit der Dateinummer
           verknüpften Objektes bzw. seines Dateizeigers.
           Man kann ein und dieselbe Nummer mehrfach verschachtelt mit
           mehreren Objekten verknüpfen ...!!!

      Umlenkungsargumente zu einem Kommando wirken temporär. Nach Ausführung
      des Kommandos wird automatisch zur ursprünglichen Verknüpfung
      zurückverknüpft.
      Bei globalen Umlenkungen muß der Programmierer für eine korrekte
      Rückführung sorgen. (siehe sane-Kommando)
      Bei Fehlermeldungen und Shell-exit werden -falls nötig- automatisch
      die beim Shell-Start vorgefundenen Verknüpfungen wieder hergestellt.

      Es darf nur eine Umlenkung pro Argument vorgenommen werden:
           richtig:   Kdo <datei1 >datei2
           falsch :   Kdo <datei1>datei2
      datei muß nicht direkt hinter > oder < stehen:
           richtig:   Kdo arg>  datei
           richtig:   Kdo arg > datei
           richtig:   Kdo arg  >datei
           richtig:   Kdo arg>datei
      Man beachte bei expliziten Voranstellungen:
           kdo2>datei             # Kommandoname ist kdo2, 1>datei
           kdo 2>datei            # Kommandoname ist kdo, 2>datei
           k>datei                # Kommandoname ist k
           b>datei                # Globale Umlenkung, binär 1>datei
           b >datei               # Kommandoname ist b
      Am besten ist, man trennt stets explizit:   Kdo arg b2>datei 1>&2

      Beispiele:

           Kdo ...  >Datei 2>ErrDatei

      Standard-Ausgabe gelangt in Datei
      und Standard-Fehlerausgabe gelangt in ErrDatei.

           Kdo ... 1>Datei 2>&1

      Handle 1 wird mit Datei verknüpft. Dann wird Handle 2 mit der Datei
      verknüpft, mit der Handle 1 verknüpft ist.
      Also werden Ausgabe und Fehlerausgabe in Datei geschrieben.

           Kdo ... 2>&1 1>Datei

      Handle 2 wird mit demjenigen Objekt verknüpft, mit dem Handle 1
      verknüpft ist, also mit dem Bildschirm, falls Handle 1 zu diesem
      Zeitpunkt mit dem Bildschirm verknüpft ist.
      Dann wird Handle 1 mit Datei verknüpft, ohne die Verknüpfung von
      Handle 2 zu ändern.
      Handle 2 wird NICHT mit Handle 1 zusammengeschlossen - Unterschied!
      Kdo1 2>&1 | Kdo2:   Ausgaben von Kdo1 mit Handle 2 gelangen NICHT
      in die Pipeline!  Zu diesem Zweck müßte man Handle 2 mit dem
      erst SPÄTER gültigen Pipe(Datei!)-Handle verknüpfen.
      Handle 2 erbt ggf.u.a. lediglich eine andere Pufferungsart von Handle 1.
      ( '|!'  in der bish ersetzt  '... 2>&1 | ...'  von sh und ksh.)

      Ein rechts von & angegebener Handle bzw. dessen Verknüpfung wird nie
      verändert. Er dient nur als Wegweiser zu dem Objekt, mit dem der
      linksstehende Handle ebenfalls verknüpft werden soll.
      Die alte Verknüpfung des linken Handle wird zerstört, sofern überhaupt
      eine vorhanden ist. Vor dieser Zerstörung wird die Verknüpfung aber
      intern gespeichert, um später wieder hergestellt werden zu können.

      Beispiele:   1>datei; 9>&1; print -u9 zu1datei; ><<; ...
                   print -u7 zu1datei 1>datei 7>&1; ...

                   echo abcdefghijklmnopqrstuvwxyz > datei
                   <>datei ; catv 8,0 ; 1>&0 ; echo AAAAA ; ><<
                   Neuer Inhalt von datei:
                        abcdefghAAAAA
                        opqrstuvwxyz
                   datei wird zum Lesen und Schreiben per Handle 0
                   geöffnet.
                   catv liest 8 Zeichen von 0 und schreibt sie
                   per Handle 1 zum Bildschirm.
                   Handle 1 wird mit 0 und damit mit datei verknüpft.
                   echo schreibt per 1 in Datei und überschreibt ab
                   der Position, die catv zurückgelassen hat, mit
                   'AAAAA\n' die Zeichen 'ijklmn'.
                   Eine Alternative:
                   <>datei ; catv 8,0 ; print -u0 AAAAA ; ><

                   HERE-Dokumente:

                        cat << END
                        hhhhhh
                          hhhh
                        hhhhhhhhhh  hhhh
                        END

                        cat > Here <<!!!
                          hhhh
                          hhhh
                        !!!

                        << EEE               (-Z-)
                          hhhhh
                          hhhhh
                          hhhhh
                        EEE
                        echo HHHHH
                        cat
                        ><

                   Nicht innerhalb von $( ) oder ` ` verwenden!
                   Ein HERE-Dokument ist quasi das Gleiche wie:
                        print [-r] '.....' | cat
                   Jedoch findet hier prinzipiell eine Interpretation
                   von Spezialzeichen innerhalb des Textes statt.
                   Wegen dieser Ersatzmöglichkeit sind die bish-HERE
                   einfach und elementar implementiert.
                   Andere Shells interpretieren den Text beispw.
                   bei  cat << \END  aufgrund von '\' (Wort-Quoting).

      Die temporären Dateien der bish werden hinsichtlich ihrer Handles
      auf Werte größer 9 justiert, so daß es garantiert keine unerwarteten
      Konflikte mit programmierten Umlenkungen geben kann.



    Ausführung von Kommandos
      geschieht gemäß folgender Reihenfolge:

      - Argumentbildung und Zuweisungen
      - Spezial-Kommandos und Schlüsselwörter zur Ablaufsteuerung
      - time-Pipeline
      - Alias-Substitution
      - Interne Kommandos I     (:, true, false, set, unset, alias, ...)
      - Interne Kommandos II    (read, cd, echo, [, [[, test, ...)
      - Shell-Funktionen        (anwenderdefiniert)
      - system-Kommandos        (aus Großbuchstaben: z.B. 'DIR')
      - Batch-Kommandos         (*.BAT)
      - Externe Kommandos I :   Shell-Scripts
      - Externe Kommandos II:   Executables

      Externe Kommandos:
      Wenn der Name kein Pfadnamen-Trennzeichen (\) enthält, wird in
      Directories gemäß dem Inhalt von $PATH nach dem Kommando gesucht.
      Wenn der Name keinen Punkt enthält, werden nacheinander die
      Endungen  "", ".com", ".exe", ".bat", ".bish"  probiert.
      Wurde ein passendes Kommando gefunden, wird untersucht, ob ein
      Shell-Script vorliegt.
      Bei einer Endung ".bat" wird unmittelbar an 'system' übergeben.
      Bei einer Endung ".bish" wird unmittelbar ein bish-Script angenommen.
      Andernfalls wird geprüft, ob die ersten beiden Zeichen in der Datei
      "#!" sind.  Wenn den Zeichen #! kein Pfadname folgt, wird
      "...\bish.exe Datei ..."  ausgeführt.
      Falls ein Pfadname folgt (z.B."#!\dos\shell.exe"), wird dieses Kommando
      anstelle von "bish.exe" verwendet.
      Wenn die Prüfung kein Shell-Script ergeben hat, wird das passende
      Kommando selbst als externes Kommando ausgeführt und nicht als
      Argument an ein Shell-Programm übergeben.

      Die Directory-Namen in der Variablen PATH können mittels der Zeichen
      ; , und SP  getrennt werden. (UNIX=':')
      Ein Trennzeichen zu Beginn oder am Ende wird als .\ interpretiert.
      Wird das aktuelle Directory nicht (explizit) angegeben, wird es
      am PATH-Ende angenommen.  Voreinstellung für PATH ist  "\dos;".
      Siehe auch CDPATH, cd, chdir.



    Spezial-Kommandos (Intern)
      Interne Kommandos haben mehrere eminente Vorteile:
      o  Argumente zu internen Kommandos dürfen tausendfach länger sein
         als die zu externen Kommandos. POSIX fordert hier mindestens 2048
         Byte als Summe aller Argumente. Üblich sind beispielsweise 250 KB.
         Interne Kommandos können hingegen xxx MB entgegennehmen.
      o  Interne können auf alle Objekte direkt und schnell zugreifen.
      o  Es entsteht eine weitere Indirektionsebene, ohne daß eval nötig ist.
      o  Interne sind schneller, da jeweils kein neuer Prozeß gestartet wird.
      Wenn nicht anders angegeben, erfolgen Ausgaben auf die Standardausgabe
      und der Exit-Code ist ohne Syntaxfehler 0.
      Eingabe-/Ausgabe-Umlenkung ist möglich.

      Alphabetische Auflistung
        .        :        alias    array    autor    base     basename bgrep
        break    casemv   casemv1  casemv2  casemv3  cat      catv     cd
        chdir    cmpf     cmpv     coder    continue conv     copy     copy1v?
        copy2v?  copymv   copymv1  copymv2  copymv3  crc      ctime    cut
        dirname  dragon   echo     env      eval     exec     exit     export
        expr     extern   false    findccc  findcs   fmode    fork     fprint
        fsize    fstat    fullname global   goend    goto     grep     hx
        ifdef    ifset    ifenv    inv      kill     let      line     link
        list     local    localset mkdirs   mktemp   move     mtime    nop
        pgr      print    prints   prompt   pwd      rabbit   read     readc
        readl    readmv   readonly rel      remove   return   run?     sane
        seek     set      sha256   sha512   shift    sleep    sortl    spreadmv
        static   stime    sumv     system   systime  tee      test     times
        tr       trap     true     type     typeset  tz       umask    unalias
        unexport unset    unsetenv ver      wait     wc       whence   writemv
        xchgv

      COMMAND.COM-Kommandos können per Großschreibung oder system-Kommando
      erreicht werden:
        BREAK  CALL    CHCP       *CHDIR(CD)     CLS       +COPY
        CTTY  +DATE   +DEL(ERASE) +DIR          *ECHO      *EXIT
        FOR    GOTO    IF          LOADHIGH(LH) +MKDIR(MD) *PATH
        PAUSE  PROMPT  REM        +RENAME(REN)  +RMDIR(RD) *SET
        SHIFT +TIME   +TYPE        VER           VERIFY     VOL
      Die in diesem Zusammenhang wichtigsten sind mit + und * gekennzeichnet.


      :     [Arg ...]
      true  [Arg ...]
                     Leerkommandos. Exit-Code ist 0.  (-Z-)
      false [n] [Arg ...]
                     Leerkommando. Exit-Code ist 1 oder n.  (-Z-)
      inv [Arg ...]
                     Leerkommando. Exit-Code wird invertiert.  (-Z-)
                     (s.o.: &|)  (s.o.: ! )

      nop            No OPeration - Dieses Kommando tut gar nichts.  (-Z-)

      . Datei [Arg ...]
                     Datei muß ein bish-Script sein und wird innerhalb(!)
                     der aktuellen Shell ausgeführt.
                     Definitionen in Datei bleiben also innerhalb der
                     aktuellen Shell bestehen!
                     Ein exit-Kommando innerhalb von Datei beendet die Shell!
                     Exit-Code stammt vom letzten ausgeführten Kommando.
                     (Unterschied:  "bish Datei" ist ein Subprozeß.)

      break [n]      Siehe oben.
      continue [n]   Siehe oben.
      goend [n]      Siehe oben.   (-Z-)

      return [n]     Beendet eine Shell-Funktion.
                     n ist der Exit-Code der Funktion.
                     Ohne Angabe von n gilt der Exit-Code des letzten
                     ausgeführten Kommandos.
                     Außerhalb von Funktionen wird ein Script
                     oder eine nichtinteraktive Shell
                     oder eine prompt-Sitzung beendet.

      exit [n]       Beendet die aktuelle Shell oder das Shell-Script
      exit -P [n]    mit Exit-Code n.                                  (-Z-)
                     Ohne Angabe von n gilt der Exit-Code des letzten
                     ausgeführten Kommandos.
                     Achtung! Innerhalb von 'script' bei '. script'
                     wird auch eine interaktive Shell beendet.
                     Hier bietet sich 'return' als Alternative an,
                     oder ein Shell-Aufruf mit Option -P.
                     Nach Aufruf 'bish -P ...' kann man die Shell nur mittels
                     'exit -P' verlassen. (s.u.: set)
                     'exit' ohne -P wirkt dann wie ein Super-return oder
                     Reset zum Kommandozeilen-Prompt, egal woher.
                     Eine interaktive Shell kann auch mit ^D oder ^Z
                     verlassen werden - bei Tastatureingabe und sofern
                     Option -I nicht gesetzt ist.

      goto Label     Lenkt die Verarbeitung zur Sprungmarke  Label:   (-Z-)
           Label:    Label  muß an der Position eines Kommandonamens stehen
                     und muß 2-7 Zeichen lang sein. (ohne :)
                     Marken können auch nebeneinander stehen.
                     Marken sind innerhalb von Funktionen und Scripts lokal.
                     In Funktionen hinein oder aus ihnen heraus kann also
                     nicht gesprungen werden. Gleiches gilt für {{ }}-Blöcke.
                     ---
                     Das goto-Kommando wurde relativ simpel implementiert;
                     im Zusammenhang mit Labels werden sehr wenig informierende
                     Daten abgespeichert.
                     Deshalb sollte man standardmäßig nur außerhalb von
                     Syntax-Konstruktionen -wie z.B. Schleifen- springen.
                     Ein Heraussprung aus solcher Syntax ist aber möglich,
                     falls man direkt auf die Grundebene springt, außerhalb
                     jeder Verschachtelungs-Syntax.
                     ---
                     Unter UNIX hat nur die C-Shell ein goto-Kommando,
                     jedoch manchmal wünscht man es sich doch.
                     Zudem ist hier 'goto $LABEL_VARIABLE' möglich.
                     Die Anzahl der Sprungmarken ist allerdings absichtlich
                     limitiert. (s.u.)
                     goto  hat keinen Exit-Code.

      pwd            Gibt stets den Namen des aktuellen Directories aus
                     und setzt die Variable PWD.
                     Die Variablen PWD und OLDPWD werden bei Wechseln
                     per system-Kommando -'außen herum'- NICHT gesetzt,
                     sondern nur durch das interne cd-Kommando.

      cd    [Arg]
      chdir [Arg]
      cd/chdir -     Wechselt das aktuelle Directory;
                     Arg wird zum aktuellen Directory.
                     Ohne Argument wird zum HOME-Directory gewechselt.
                     Die Variablen PWD und OLDPWD werden gesetzt.
                     Mit Argument '-' wird zum  $OLDPWD  gewechselt.
                     cd berücksichtigt den Inhalt der Variablen CDPATH,
                     für die auch die PATH-Syntax gilt.
                     Standard-cd-Pfad ist:  ".;\" .
                     cd wechselt auch das Laufwerk, falls mit angegeben.
                     Beispiel:
                     Wenn ein Directory  \usr\sh\cmd\init  existiert
                     und CDPATH  \usr\sh  enthält, genügt die Angabe
                     von  cd cmd\init, um nach  init  zu wechseln.

      let Arg ...    Jedes Argument ist ein separater arithmetischer
                     Ausdruck, der berechnet wird. (siehe oben)
                     Der Exit-Code ist 0, wenn das letzte Ergebnis ungleich
                     0 ist, andernfalls 1.
                     ((...)) setzt den Exit ebenfalls, $(()) jedoch nicht.

      test [Arg ...] Siehe test(K).
                     [ und [[ sind Alternativnamen dieses Kommandos, als
                     letztes Argument muß dabei ] bzw. ]] gegeben werden.
                     Siehe oben.

      run? [!] [Arg1] [Arg2]                                            (-Z-)
                     Die Argumente Arg1 und Arg2 enthalten jeweils bish-Code.
                     Deren Inhalt wird in Abhängigkeit des aktuell
                     vorliegenden Exit-Codes ausgeführt:
                     Bei Exit = TRUE  wird der Inhalt des Arg1, und
                     bei Exit = FALSE wird der Inhalt des Arg2
                     zur Ausführung gebracht.
                     Ist das erste Argument ein '!', wird der Exit-Code
                     invertiert bewertet.
                     Ein Argument wird evaluiert, wenn es existiert und der
                     Inhalt nicht leer ist.
                     Ein Argumentinhalt darf maximal 2040 Zeichen umfassen.
                     Dieses Kommando selbst setzt nicht den Exit-Code.
                     Beispiel:
                          set -B; false
                          run?  '....... echo $? ..........' \
                                '....... echo $? ......'
                     Dieses Kommando ist dazu gedacht, mit wenig Schreibarbeit
                     abhängigen Code in ein oder zwei Zeilen unterzubringen.
                     Argumente wie folgt in einer Schleife:
                          run?  continue break
                     sind nicht möglich, da diese Kommandos als Argumente
                     eines Kommandos die umgebende Schleife nicht sehen.
                     Sie müssen an der Position eines Kommandos stehen.
                          run?  '3>&2' 'k=$n'
                     Meistens muß mittels '...' eingefaßt werden, damit
                     keine Expansion der Argumente zu run? stattfindet.
                     Es sei denn, dies ist beabsichtigt.

      echo [Arg ...] Siehe echo(K), print.

      cat [ -svtemnBT ] [-] [ datei ... ]                               (-Z-)
                     Verkettet Dateiinhalte.
                     Siehe cat(K).

      tr [ -cds ] [ string1 [ string2 ] ]                               (-Z-)
                     Setzt um, löscht und reduziert Zeichen(folgen).
                     Siehe tr(K).

      wc [ -lwcm ] [ datei ... ]                                        (-Z-)
                     Zählt Zeilen, Worte und/oder Zeichen,
                     oder maximale Längen.
                     Siehe wc(K).

      cut -cListe [-d'c...'] [-s] [ datei ... ]                         (-Z-)
          -fListe
          -lListe
                     Schneidet Zeichen(folgen/felder), Zeilen oder Worte
                     aus Dateien heraus.
                     Siehe cut(K).

      expr  string : regulärer_ausdruck [[+=] ersatztext]               (-Z-)
                     Vergleicht und selektiert Zeichenfolgen.
                     Siehe expr(K), regexp®, xregexp®.

      grep [ -FSVXBAchilnm[#]qsvyxL ] [ vname ] [ -e ] RA [ datei ... ] (-Z-)
                     Durchsucht Textzeilen nach einem Suchmuster.
                     Siehe grep(K), expr(K), regexp®, xregexp®.

      bgrep  [-gclihstvqM] [name] [-oN|-ON] [-nN]  [-f]Folge  datei ...
      bgrep  [-gclihstvqM] [name] [-oN|-ON] [-nN]  -Fdatei  datei ...
      bgrep  [-gclihstvqM] [name] [-oN|-ON] [-nN]  -Vname  datei ...    (-Z-)
                     Durchsucht Dateien nach einer Byte-Folge.
                     Siehe bgrep(K).

      line  [ {-|+}a[-[e]] ] [ datei ... ]                              (-Z-)
                     Gibt (nicht-)selektierte Zeilen aus.
                     Siehe line(K).

      rel  [arg ...] [ < datei ] [ > datei ]                            (-Z-)
                     Entfernt aufeinanderfolgende gleiche Zeilen.
                     Siehe rel(K).

      tee  [ -T ] [ datei ]   (tee  datei < idatei | kdo)               (-Z-)
                              (kdo | tee datei | kdo)
                     Bildet ein T-Stück innerhalb einer Pipeline.
                     Siehe tee(K).

      cmpf  [-q]  datei1 datei2  [offs1 [offs2]]                        (-Z-)
                     Vergleicht Dateiinhalte byte-weise.
                     Siehe cmp(K).

      hx  [-a[d][b]] [-b[d][b]] [-t[g78d]]  [-o[0]N] [-nN] [-[-]]  [datei ...]
              h  k       h  w                                           (-Z-)
              H  K       H  l
                [x]N    c[g78d]
                     Wandelt Daten um in lesbare Darstellungsformen.
                     Siehe hx(K).

      pgr  [-] [-zahl] [-cefns] [ datei(en) ...]                        (-Z-)
                     Kommando zum komfortablen Lesen von Textdateien (pager)
                     Siehe pg(K).

      coder  -e  [-nv]  [-c code64]  [ quell_vname [ziel_vname]]        (-Z-)
      coder  -d  [-sv]  [-c code64]  [[quell_vname] ziel_vname ]
      coder  -e  [-n]   [-c code64]  [ quell_datei [ziel_datei]]
      coder  -d  [-s]   [-c code64]  [[quell_datei] ziel_datei ]
      coder  -ue        [ quell_datei ]  ziel_datei_eintrag  (uuencode)
      coder  -ud [-s]   [ quell_datei ]                      (uudecode)
      coder  -A|-C
                     Kodiert Dateien in Textformen um, und umgekehrt.
                     Siehe coder(K).

      crc  =32
      crc  =64
      crc  [ -vV{32|64} ] [name] [name] [ datei ... ]                   (-Z-)
      crc  < datei
      kdo  | crc
                     Errechnet CRC32- oder CRC64-Prüfsummen.
                     CRC64 benutzt das Polynom ECMA182.
                     Die Optionen müssen als ein Argument angegeben werden.
                     Die Reihenfolge der Optionszeichen(folgen) ist beliebig.
                     =32  Wählt dauerhaft CRC32 (Voreinstellung).
                     =64  Wählt dauerhaft CRC64.
                     -32  Wählt CRC32; hat Vorrang vor =32 =64.
                     -64  Wählt CRC64; hat Vorrang vor =32 =64.
                     -v   Der Name einer Shell-Variable wird angegeben, in die
                          der generierte Wert gespeichert wird.
                     -V   Der Name einer Shell-Variable wird angegeben, aus
                          deren Inhalt der CRC generiert wird.
                     Bei Verwendung von Shell-Variable(n) wird nur ein CRC
                     generiert. Es ist konzeptionell günstiger, wenn der
                     Umgang mit vielen Quellen und Zielen in einem Skript
                     vorgenommen wird, u.a. da dieses Kommando intern ist und
                     somit keinen neuen Prozeß startet.
                     Das Kommando liest auch von der Standard-Eingabe (fd=0).
                     Beim Lesen vor der Tastatur werden hierbei anhängende
                     Zeichen \r und \n entfernt. Beenden durch <Enter>
                     und ^D bzw. ^Z.
                     Ohne Option -v erfolgt Ausgabe zur
                     Standard-Ausgabe:  [datei:]crc.
                     Siehe auch crc(K); Die Beschreibung hier hat Priorität.

      sha256  =23
      sha512  =23
      sha256 [-23scv] [name] [s_str] [c_str] [datei...]                 (-Z-)
      sha512 [-23scv] [name] [s_str] [c_str] [datei...]                 (-Z-)
                     Diese beiden Kommandos generieren Hash-Werte mit einer
                     Länge von 64 bzw. 128 Hexadezimal-Zeichen.
                     Beispiel:  2ca69efd4ea5af91a637f19ba0bab8b081d2c03773\
                     c4a72fcbf8817c856b33ef
                     Die Optionen müssen als ein Argument angegeben werden.
                     Die Reihenfolge der Optionsbuchstaben ist beliebig.
                     Die Reihenfolge der Argumente ist nicht beliebig!
                     -2   Wählt die Version SHA2. Dies ist die Voreinstellung.
                     -3   Wählt die Version SHA3 - den Keccak-Algorithmus.
                     =2   Wählt SHA2 dauerhaft, erspart -2.
                     =3   Wählt SHA3 dauerhaft, erspart -3.
                     -s   Eine Zeichenkette s_str wird als Argument angegeben,
                          zu der ein Hash-Wert generiert wird.
                     -c   Eine Zeichenkette c_str wird als Argument angegeben
                          oder als Variableninhalt übergeben, mit der der
                          generierte Hash-Wert verglichen wird.
                     -v   Der Name einer Shell-Variable wird angegeben, in die
                          der generierte Wert gespeichert wird.
                          Zuvor wird (bei Option -c) der Inhalt als c_str
                          festgehalten.
                     Ohne Option -v wird der Hash auf 'stdout' ausgegeben.
                     Datenquellen sind Zeichenkette s_str, die Standard-Eingabe
                     'stdin' und Dateien.
                     Ohne s_str und Dateien werden Daten von 'stdin' gelesen.
                     Falls hinter '=' nichts oder nicht 2|3 folgt, wird der
                     normale Zustand und -2 (Voreinst.) hergestellt.
                     Die maximale Datenlänge beträgt etwa 2300000 Tera-Byte.
                     OPT   ARGS DATEIEN
                     scv   v s  [datei...]
                     sc.   s c  [datei...]
                     s.v   v s  [datei...]
                     .cv   v    (datei...)
                     s..   s    [datei...]
                     ..v   v    (datei...)
                     .c.   c    (datei...)
                     ...        (stdin)
                     Der Vergleich mit c_str erfolgt bei der ersten Möglichkeit
                     und dann nicht wieder.
                     Der Exit-Wert des Kommandos wird entsprechend gesetzt.
                     Das Speichern in eine Variable erfolgt bei der ersten
                     Möglichkeit und dann nicht wieder.
                     Bei weiteren Datenquellen wird deren Hash auf 'stdout'
                     ausgegeben.
                     Die Algorithmen wurden gemäß der Dokumentation des
                     'National Institute of Standards and Technology (NIST)'
                     implementiert.
                     Es ist _praktisch_ nicht möglich, zu einem gegebenen
                     Hash-Wert einen zugehörigen Text zu finden.
                     Ebenso nicht möglich ist es, durch zwei verschiedene
                     Texte gleiche Hash-Werte zu generieren.
                     Jeder Text/Dateninhalt der Welt hat folglich einen
                     individuellen Wert, wie ein Fingerabdruck.
                     Theoretisch ist das allerdings nicht zutreffend.

      rabbit passwort
      rabbit schlüssel [init] quelldatei zieldatei                      (-Z-)
                128    [ 64 ]  zeichen
                 32    [ 16 ]  zeichen
                 16    [  8 ]  zeichen
                     Dieses Kommando implementiert den Rabbit-Algorithmus.
                     Es handelt sich um eine bekannte und sehr bewährte
                     Stromverschlüsselung. ENTschlüsselung erfolgt genau
                     so, wie die VERschlüsselung.
                     Als Schlüssel- und Init-Vektor müssen Zeichenketten
                     mit 128 bzw. 64 Zeichen Länge übergeben werden.
                     Beispielsweise wie die folgende durch 'coder -C'
                     erzeugte:  2CG8!]m"hAMjcu:TO)9ty*>{[q;v,6BnEoH
                                P\%R/.Uf30D(5dKV\Y1N`#<k7gLes+
                     Das Kommando verwendet nur das jeweils erste Bit
                     der Zeichen (gerade|ungerade), sodaß Reihen aus
                     128 bzw. 64 Bit entstehen.
                     Solche Zeichenketten sind in Shell-Skripten sehr gut
                     handhabbar. Sie enthalten nicht die drei Zeichen (' =).
                     Siehe auch: 'conv -i name'
                     Schlüssel und IV können auch durch 32 bzw. 16 oder
                     16 bzw. 8 Zeichen angegeben werden.
                     Dadurch entsteht:
                          Zeichen:  gerade Bit=0, ungerade Bit=1
                          Hexadezimal-Zeichen
                          Zeichen mit ihren je 8 Bit
                     Bit-Effektivität:  1, 4, 8 Bit pro Zeichen.
                     Der Init-Vektor muß nicht angegeben werden.
                     Das reduziert jedoch (nicht überraschend) die Sicherheit.
                     Das Kommando muß zuvor durch ein Paßwort freigegeben
                     werden. Ein falsches Paßwort löscht eine eventuell
                     bereits erteilte Freigabe. Eine Freigabe bleibt für
                     die Dauer eines bish-Prozesses bestehen.
                     Der Algorithmus kann bis zu 2^68 Bytes generieren
                     ohne ihn neu zu starten (key,iv).
                     Rabbit hat seit 2003 keine Schwächen gezeigt!

      dragon passwort
      dragon schlüssel init  quelldatei zieldatei                       (-Z-)
                256    256   zeichen
                 64     64   zeichen
                 32     32   zeichen
                     Dieses Kommando implementiert den Dragon-Algorithmus.
                     Es handelt sich um eine Stromverschlüsselung.
                     ENTschlüsselung erfolgt genau so, wie die VERschlüsselung.
                     Als Schlüssel- und Init-Vektor müssen Zeichenketten
                     mit 256 Zeichen Länge übergeben werden.
                     Beispielsweise wie die folgende durch 'coder -C'
                     erzeugte:  2CG8!]m"hAMjcu:TO)9ty*>{[q;v,6BnEoH
                                P\%R/.Uf30D(5dKV\Y1N`#<k7gLes+
                     Das Kommando verwendet nur das jeweils erste Bit
                     der Zeichen (gerade|ungerade), sodaß Reihen aus
                     256 Bit entstehen.
                     Solche Zeichenketten sind in Shell-Skripten sehr gut
                     handhabbar. Sie enthalten nicht die drei Zeichen (' =).
                     Siehe auch: 'conv -i name'
                     Schlüssel und IV können auch durch 64 oder 32 Zeichen
                     angegeben werden.
                     Dadurch entsteht:
                          Zeichen:  gerade Bit=0, ungerade Bit=1
                          Hexadezimal-Zeichen
                          Zeichen mit ihren je 8 Bit
                     Bit-Effektivität:  1, 4, 8 Bit pro Zeichen.
                     Das Kommando muß zuvor durch ein Paßwort freigegeben
                     werden. Ein falsches Paßwort löscht eine eventuell
                     bereits erteilte Freigabe. Eine Freigabe bleibt für
                     die Dauer eines bish-Prozesses bestehen.
                     Der Algorithmus kann bis zu 2^61 Bytes generieren
                     ohne ihn neu zu starten (key,iv).

      print [-nru[d]-] [arg ...]
                     Siehe Kommando echo --> echo(K)
                     -n      Unterdrückt den abschließenden Zeilenvorschub.
                     -r      Unterdrückt die Funktion der Spezialzeichen=
                             folgen (%c,%n,...) des echo-Kommandos.
                     -u[d]   d (digit) gibt einen Ausgabe-Handle an.
                             Ohne -u oder ohne d gilt Handle=1.
                     --      Falls das erste auszugebende Argument mit
                             '-' beginnt.
                     Die Optionen müssen als erstes Argument angegeben werden.

      prints [[v]format[-]] [vname] [arg ...]                           (-Z-)
                     Dieses Kommando schreibt seine Argumente rechts- oder
                     linksbündig oder zentriert innerhalb einer Feldlänge
                     oder unaufgefüllt oder vorne oder hinten abgeschnitten
                     zur Standard-Ausgabe.
                     format-string:  [v]s[.][-:][{ +}][fx][feldlänge][{btn}]...
                     v     Ausgabe in Variable 'vname'. (Kein NL am Ende.)
                     s     Leitet jedes Argumentformat ein.
                     .     Geht zum nächsten 's' und ignoriert zug. Argument.
                     u[d]  Angabe eines Handle-Digit, Voreinstellung ist 1.
                     -     Linksbündige statt rechtsbündige Ausgabe.
                     :     Zentrierte Ausgabe.
                     ' +'  Leerzeichen oder '+' wird einem Argument vorange=
                           gestellt, falls dieses mit 0...9 beginnt.
                     fx    Für x kann ein beliebiges Zeichen eingesetzt werden,
                           mit dem dann zur Feldlänge aufgefüllt wird, falls
                           das zugehörige Argument kürzer als diese ist.
                           Voreingestellt ist  'f '.
                     Fddd  Nach F kann eine ein- bis dreistellige Dezimalzahl
                           eingesetzt werden, die ein Zeichen repräsentiert,
                           das als Füllzeichen verwendet wird.
                           Nötigenfalls führende Nullen angeben!
                     feldlänge
                           Zahl  0 ... 2^31-1
                     btn   Leerzeichen, Tab oder Zeilenvorschub wird nach
                           dem zugehörigen Argument ausgegeben (s.u.).
                     format-
                           Der abschließende Zeilenvorschub wird unterdrückt
                           bei Angabe eines '-' am Ende des Format-strings.
                     Falls weniger Formatelemente als Argumente angegeben
                     werden, wird das letzte Format weiterbenutzt.
                     Falls weniger Argumente als Formatelemente angegeben
                     werden, wird das letzte Argument weiterbenutzt.
                     Wird lediglich ein Format-Argument angegeben, wird so
                     getan, als gäbe es Argumente mit der Länge Null.
                     Exit-Code ist 2 bei Fehlern von System-Funktionen,
                     sonst 0.
                     Dieses Kommando ist überraschend universell!
                     Beispiele:
                        #  prints ssss aaa bbb' '
                        aaabbb bbb bbb
                        #  prints sf.20 aaa bbb
                        .................aaa.................bbb
                        #  prints s20sf.20
                                            ....................
                        #  prints s2s3s-3 abcdef ABCDEF 123456
                        efDEF123
                        #  prints sf06s' '  123 333 -222
                        000123 333-222
                        #  prints s10  `echo "..."`
                     Bei Angabe von 'u' nicht die Feldlänge direkt folgen
                     lassen, sondern gegebenenfalls explizit 'su1..' angeben!
                     Ein u-Handle wird dauerhaft benutzt, wenn es nicht mittels
                     einer erneuten Angabe geändert wird.
                     btn:
                     Es kann erweitert »bbb5bnb1234tt1tnn2« angegeben werden.
                     Dabei wird das letzte Zeichen aus btn berücksichtigt
                     und die Anzahlen werden aufaddiert.
                     Bei Zeilenvorschub \r\n wird nur einmal \r ausgegeben.
                     Z='1234  vvvvvvvvvvvvvvvv  TTTTTTTTTT'
                     prints s5b5s-28s  $Z
                     » 1234     vvvvvvvvvvvvvvvv            TTTTTTTTTT«


      fprint [+str] fName...     (-Z-)
                     Dieses Kommando ist reichlich ungewöhnlich:
                     Man kann damit die Inhalte von Funktionskörpern
                     zur Standard-Ausgabe schreiben.
                     Solche Inhalte können eine fast beliebige Ansammlung
                     von Zeichen sein. Nur die Regeln, die den Funktionsleser
                     Anfang und Ende erkennen lassen, müssen beachtet werden!
                     Eine Funktion mit Textinhalt soll man natürlich nicht
                     als Kommando aufrufen.
                     Als Option kann eine Zeichenkette angegeben werden,
                     die den Zeilen aus den Funktionskörpern vorangestellt
                     wird.
                     Exit ist FALSE, falls ein Name (noch) nicht bekannt ist.
                     Siehe oben die Syntax zu Shell-Funktionen.

      read [-u#] [Name?Prompt] [Name ...]     (Name='Name|-') (-Z-)
                     Der Eingabemechanismus der Shell.
                     Es wird eine Zeile gelesen und gemäß dem Inhalt der
                     Variablen IFS in Argumente zerteilt.
                     Diese Argumente werden der Reihe nach den angegebenen
                     Variablennamen zugewiesen.
                     Überzählige Argumente werden dem Inhalt der zuletzt
                     angegebenen Variablen hinzugefügt.
                     Bei zuwenig Argumenten werden die Variablen entsprechend
                     mit dem Null-String gesetzt.
                     -u#     #==0...9  Wahl eines offenen Handles.
                             Standard-Einstellung ist 0.
                     Name darf auch '-' lauten, zwecks Überspringen.
                     An den ersten Namen kann nach einem ? ein Prompt-String
                     angehängt werden. Diese Funktion ist nur bei einer
                     interaktiven Shell gegeben, wenn Standard-Eingabe und
                     Standard-(Fehler-)Ausgabe mit einem Terminal
                     verknüpft sind.   (dabei  "Name?Prompt"  maskieren!)
                     Vor und nach diesem Kommando kann das seek-Kommando
                     verwendet werden.
                     Bei diesem Kommando dürfen einer Variablen maximal
                     254 Zeichen zugewiesen werden (nur DOS16).
                     Exit=FALSE  bei Fehlern oder wenn keinerlei Zeichen
                     gelesen werden konnten; dabei kein Variablensetzen.
                     Beispiele:
                          #  read
                          #  read "-?<Enter>"
                          #  read inp
                          #  read "inp?<Enter>" inp2
                     sind Standard-Verwendungen.
                          #  read A <datei
                     liest eine Zeile aus datei.
                          #  <datei ; read B ; read C ; read D ; ><
                     liest drei Zeilen aus datei. (Schnelles Lesen!)
                          #  echo 'a b   c' | read r1 r2
                     danach:  r1=a  r2='b c'
                          #  read - - f3 -
                     liest das dritte Feld. '-' ist blind für weitere Felder.

                     Wenn Kommandos, wie beispielsweise cat, von der
                     Standard-Eingabe lesen, kann eine solche Eingabe
                     durch <Ctrl><D> oder <Ctrl><Z> (^D^Z) beendet werden.
                     Das gilt nur für Tastatur-Eingabe.
                     (s. readc(K))
                     Beispielsweise mit  zeile="`line`"  kann man Eingaben
                     machen, ohne daß Zwischenraum entfernt wird.

      readl [-u#0] [ Name ... ]                               (-Z-)
                     Wie 'read', die Zeilen bleiben jedoch völlig
                     unbearbeitet.
                     Zeilenvorschübe werden nicht mit übertragen.
                     (Leere Variable == Leerzeile)
                     (Exit=FALSE == Dateiende)
                     -u#     #==0...9  Wahl eines offenen Handles.
                             Standard-Einstellung ist 0.
                     -0      0 ('\0') gilt als Zeilenende!
                             (siehe Kommando 'list')
                     Alle angegebenen Variablen werden mit dem(selben)
                     Zeileninhalt gefüllt.
                     Der Vorteil gegenüber 'line' ist, daß eine Datei
                     dauerhaft geöffnet bleibt und stetig vorrückend,
                     Zeile für Zeile, gelesen wird.
                     Vor und nach diesem Kommando kann das seek-Kommando
                     verwendet werden.
                     Bei diesem Kommando dürfen einer Variablen maximal
                     1535 Zeichen zugewiesen werden (nur DOS16).
                     Bei sofortigem EOF kein Variablensetzen.



      readmv
      writemv
      spreadmv
      copymv  copymv1  copymv2  copymv3
      casemv  casemv1  casemv2  casemv3
                     Diese nachfolgend beschriebenen Kommandos, die das gleiche
                     Konzept verfolgen, können sehr gut zusammen arbeiten.
                     Sie ergänzen sich vorzüglich.
                     Alle speichern Variablen-Zugriffsstrukturen dauerhaft.
                     Diese Strukturen werden durch anmelden/registrieren von
                     Namen existierender Variablen beschafft und gespeichert.
                     Wenn diese Kommandos später ohne Argumente arbeiten, ist
                     alles für die jeweilige Arbeit Notwendige bereits
                     vorhanden. Zusätzlich entfallen die Argumente an sich.
                     Besonders sinnvoll ist dieses Konzept, wenn mit mehreren
                     und immer den gleichen Variablen sehr oft hintereinander
                     immer die gleiche Arbeit verrichtet werden soll.
                     Die ersten drei Kommandos sind relativ aufwendig und
                     bieten eine hohe Variabilität. Das einfachere Kommando
                     copymv  ist dafür ein Dreifach-Kommando.
                     Verwendungs-Beispiel:
                     Das Kommando  readmv  liest Datensätze, die von  findccc
                     und  findcs  erzeugt wurden (Zeilen).
                     Kommando  spreadmv  filtert aus dem jeweiligen Datensatz
                     die einzelnen Datenwörter heraus und kopiert sie in
                     entsprechend viele Variablen.
                     Kommando  copymv  kopiert diese Datenwörter, weil oft der
                     vorherige Datensatz später noch gebraucht wird.
                     Kommando  catv  kann die Datenwörter mit Veränderungen zu
                     einem Datensatz zusammen verketten, und  writemv  schreibt
                     diese Datensätze in eine große Datensatz-Variable.
                     Daraus kann  readmv  diese erneut lesen, für einen
                     weiteren Arbeitsgang.
                     Nach einzelnen Anmeldungen von Variablen können
                     hunderttausende von Datensätzen immer wieder in gleicher
                     Weise übersichtlich und rasend schnell verarbeitet werden!



      readmv  [[delim,]offs,]iname ...  =oname ...                 (-Z-)
      readmv  -name ... iname ... =oname ...
      readmv  - iname = =oname -= ... =- ...
      readmv         (Standardverwendung nach namen-Anmeldung)
                     ---
                     Etwa wie 'readl', mit Syntax wie 'catv'.
                     Siehe nachfolgend die Beschreibung zu 'writemv'.
                     Es wird beliebig aus existierenden Variablen gelesen,
                     die zuvor als iname(n) angemeldet werden müssen.
                     Es wird in bereits existierende Variablen geschrieben,
                     die zuvor als =oname(n) angemeldet werden müssen.
                     Es können bis zu 16 Variablen gleichzeitig
                     angemeldet sein.
                     Es müssen mindestens ein iname und ein oname
                     registriert sein. Bei einem iname sind weitere
                     Angaben im Argument möglich.
                     Eine Anmeldung kann eine Erstanmeldung oder eine
                     Wiederholungsanmeldung sein. Bei einer Erstanmeldung
                     werden  offs=0  und  delim=\n  voreingestellt.
                     Angaben im Argument können diese Voreinstellung ändern.
                     Ein zuletzt angegebenes iAnmelde-Argument setzt den dort
                     angegebenen iNamen aktiv.
                     Ein zuletzt angegebenes oAnmelde-Argument setzt den dort
                     angegebenen oNamen aktiv.
                     Dabei können beliebig neue Daten mitgegeben werden.
                     Das Kommando arbeitet stets mit einem aktiven iNamen
                     und einem aktiven oNamen.
                     Eine iVariable wird bis zur Länge ${#iname} gelesen.
                     Der Offset wird nach jedem Lesen direkt hinter die
                     soeben gelesenen Daten gesetzt. Wenn das Datenende
                     erreicht ist, retourniert  readmv  mit Exit=FALSE.
                     Eine oVariable wird stets von Beginn an beschrieben.
                     Danach wird die Länge ${#oname} entsprechend gesetzt.
                     Diese Länge kann auch durch die Kommandos 'set : ...'
                     und 'local : ...' gesetzt werden.
                     Eine Anmeldung bei bereits vorliegendem Angemeldetstatus
                     aktiviert lediglich, sofern dabei keine Parameterwerte
                     explizit angegeben sind:
                        d,o,iname
                        o,iname
                        iname
                        d,,iname
                        ,,iname
                        ,o,iname
                     Wie zu sehen ist, werden die Parameter anhand der
                     Position ihrer Werte erkannt.
                     Die letzten beiden Zeilen zeigen eine _Abschaltung_
                     des Delimiters  delim='', also einen leeren Delimiter.
                     Variablen, die per Name und nicht per Ziffern angegeben
                     sind, werden von readmv selbst 'ausgepackt' (o):
                        readmv o,iname
                     Selbstverständlich ist  $d,$o,$iname  möglich.
                     Hier packt die Shell eben die Inhalte aus.
                     ---
                     Eine Abmeldung -name löscht den Zugriff,
                     falls es sich um einen aktiven Namen handelt!
                     Eine Abmeldung - meldet alle iNamen ab
                     und löscht den Zugriff.
                     Eine Abmeldung = meldet alle oNamen ab.
                     und löscht den Zugriff.
                     Eine Abmeldung -= oder =- meldet alle Namen ab
                     und löscht den Zugriff.
                     ---
                     Bei Aufruf von readmv ohne Argumente wird gelesen
                     und geschrieben und der Lese-Offset dem Delimiter
                     entsprechend weitergesetzt.
                     Falls kein Delimiter in den gelesenen Daten gefunden
                     wird oder wenn der Delimiter abgeschaltet ist, wird
                     die iVariable in einem Zug vollständig gelesen.
                     Ein Delimiter wird nicht in eine oVariable übertragen.
                     Falls mehrere Delimiter hintereinander vorkommen, wird
                     auch mehrmals hintereinander die oVariable leer gesetzt!
                     Das sind dann (quasi) Leerzeilen.
                     Der Delimiter kann auf jeden Wert von 0..255
                     gesetzt werden, und zwar per Dezimalzahl oder durch
                     ein Zeichen ungleich den Ziffern '0'-'9'.
                     Bei delim='\n' wird '\r\n' automatisch berücksichtigt.
                     ---
                     Eine Delimiter-Angabe  12:34:56:78,  ist möglich.
                     Dadurch ändert sich das Verhalten dahingehend, daß
                     beliebig viele Delimiter überlesen werden, bis Daten
                     vorliegen, die keine Delimiter sind und daher in die
                     oVariable übertragen werden.
                     Es können hier maximal 11 Delimiter angegeben werden.
                     Eine Angabe  34:,  gestattet den anderen Modus mit nur
                     einem Delimiter, denn der ':' ist die Erkennung dafür.
                     Übliche Zwischenraumzeichen sind:  9:10:11:12:13:32
                     ---
                     Durch einen Aufruf »readmv« wird $. jeweils auf die
                     Offset-Schrittweite gesetzt, bei Exit=TRUE.
                     Dadurch ist ein Vorliegen von '\r\n' erkennbar.
                     Die Zielvariablen werden durch readmv nicht vergrößert,
                     sie müssen vorher schon groß genug sein.
                     Die Größe der Zielvariablen ${#Z} variiert je nach
                     aktuell darin enthaltener Datenmenge/Zeilenlänge.
                     Eine Veränderung der internen Länge ${:Z} jedoch wird
                     bei bei  readmv  angemeldeten Variablen blockiert.
                     ---
                     Es ist der Gültigkeitsbereich lokaler Variablen
                     zu beachten!
                     readmv  erfährt es nicht, wenn angemeldete Variablen
                     durch andere Kommandos gelöscht oder verändert werden!
                     Allerdings informiert der Variablen-Manager  readmv
                     bei Änderung von Basiszeigern durch realloc().
                     ---
                     Vergleich readmv <> readl:
                     --------------------------
                     readmv:   3.52 real      3.46 user      0.00 sys
                     readl :  14.38 real      6.05 user      8.09 sys
                     (PIII/700)

                     Test-Script:
                     ------------
                        set Z:.250
                        
                        [ "$1" == readmv ] && {
                           set F:.300000
                           catv =F: <bish.c   #7700 Zeilen
                           readmv F =Z
                           to 100 repeat
                           do
                              readmv 0,F
                              while readmv
                              do
                                 nop
                              done
                           done
                        }
                        
                        [ "$1" == readl ] && {
                           to 100 repeat
                           do
                              <bish.c
                              while readl Z
                              do
                                 nop
                              done
                              ><
                           done
                        }
                     Es ist zu beachten, daß Variablen 100 MegaByte groß
                     sein können!
                     Das Kommando catv in Zusammenarbeit mit conv könnte
                     letztlich auch die Aufgabe von readmv erfüllen.
                     Jedoch das Lesen bis jeweils zum (angebbaren) Delimiter
                     hat den Ausschlag für readmv gegeben.
                     catv kann die Daten von readmv weitergeben:
                        catv Z /%r%n =o,,Ziel
                        let "o+=${#Z}+2"
                     ---



      writemv  iname ... =[[anhang,]länge,]oname ...               (-Z-)
      writemv  -name ... iname ... =oname ...
      writemv  - iname = =oname -= ... =- ...
      writemv        (Standardverwendung nach namen-Anmeldung)
                     ---
                     Konzeptionell wie das vorstehend beschriebene
                     Kommando  readmv.
                     Es wird beliebig aus existierenden Variablen gelesen,
                     die zuvor als iname(n) angemeldet werden müssen.
                     Es wird in bereits existierende Variablen geschrieben,
                     die zuvor als =oname(n) angemeldet werden müssen.
                     Es können bis zu 16 Variablen gleichzeitig
                     angemeldet sein.
                     Es müssen mindestens ein iname und ein oname
                     registriert sein. Bei einem oname sind weitere
                     Angaben im Argument möglich.
                     Eine Anmeldung kann eine Erstanmeldung oder eine
                     Wiederholungsanmeldung sein. Bei einer Erstanmeldung
                     wird  anhang=\n  voreingestellt.
                     Angaben im Argument können diese Voreinstellung ändern.
                     Ein zuletzt angegebenes iAnmelde-Argument setzt den dort
                     angegebenen iNamen aktiv.
                     Ein zuletzt angegebenes oAnmelde-Argument setzt den dort
                     angegebenen oNamen aktiv.
                     Dabei können beliebig neue Daten mitgegeben werden.
                     Das Kommando arbeitet stets mit einem aktiven iNamen
                     und einem aktiven oNamen.
                     Eine iVariable wird stets komplett gelesen (${#iname}).
                     Eine oVariable wird stets hinter ihr aktuelles Ende
                     beschrieben: ${#oname}. Diese Länge wird nach jedem
                     Schreiben weitergesetzt. Diese Länge kann durch eine
                     explizite Angabe von 'länge' gesetzt werden.
                     Hinter den Daten aus einer iVariablen wird jeweils ein
                     'anhang' in eine oVariable geschrieben, falls der Anhang
                     nicht abgeschaltet ist.
                     Eine Anmeldung bei bereits vorliegendem Angemeldetstatus
                     aktiviert lediglich, sofern dabei keine Parameterwerte
                     explizit angegeben sind:
                        a,l,oname
                        l,oname
                        oname
                        a,,oname
                        ,,oname
                        ,l,oname
                     Wie zu sehen ist, werden die Parameter anhand der
                     Position ihrer Werte erkannt.
                     Die letzten beiden Zeilen zeigen eine _Abschaltung_
                     des Anhangs  anhang='', also einen leeren Anhang.
                     Variablen, die per Name und nicht per Ziffern angegeben
                     sind, werden von writemv selbst 'ausgepackt' (l):
                        writemv l,oname
                     Selbstverständlich ist  $a,$l,$oname  möglich.
                     Hier packt die Shell eben die Inhalte aus.
                     ---
                     Eine Abmeldung -name löscht den Zugriff,
                     falls es sich um einen aktiven Namen handelt!
                     Eine Abmeldung - meldet alle iNamen ab
                     und löscht den Zugriff.
                     Eine Abmeldung = meldet alle oNamen ab.
                     und löscht den Zugriff.
                     Eine Abmeldung -= oder =- meldet alle Namen ab
                     und löscht den Zugriff.
                     ---
                     Bei Aufruf von writemv ohne Argumente wird gelesen
                     und geschrieben und der Schreib-Offset der jeweiligen
                     Datenmenge entsprechend weitergesetzt.
                     Der Anhang kann auf jeden Wert von 0..255
                     gesetzt werden, und zwar per Dezimalzahl oder durch
                     ein Zeichen ungleich den Ziffern '0'-'9'.
                     Eine Anhang-Angabe  12:34:56:78,  ist möglich.
                     Es können hier maximal 11 Werte angegeben werden.
                     Übliche Zwischenraumzeichen sind:  9:10:11:12:13:32
                     ---
                     Durch einen Aufruf »writemv« wird $. jeweils auf die
                     Längen-Schrittweite gesetzt, bei Exit=TRUE.
                     Die Zielvariablen werden durch writemv nicht vergrößert,
                     sie müssen vorher schon groß genug sein.
                     Eine Veränderung der internen Länge ${:Z} wird
                     bei bei  writemv  angemeldeten Variablen blockiert.
                     ---
                     Es ist der Gültigkeitsbereich lokaler Variablen
                     zu beachten!
                     writemv  erfährt es nicht, wenn angemeldete Variablen
                     durch andere Kommandos gelöscht oder verändert werden!
                     Allerdings informiert der Variablen-Manager  writemv
                     bei Änderung von Basiszeigern durch realloc().



      spreadmv  [delim,]iname ...  =oname ...                 (-Z-)
      spreadmv  -name ... iname ... =oname ...
      spreadmv  - iname = =oname -= ... =- ...
      spreadmv       (Standardverwendung nach namen-Anmeldung)
                     ---
                     Siehe auch die vorstehenden Beschreibungen
                     zu 'readmv' und 'writemv'.
                     Es wird beliebig aus existierenden Variablen gelesen,
                     die zuvor als iname(n) angemeldet werden müssen.
                     Es wird in bereits existierende Variablen geschrieben,
                     die zuvor als =oname(n) angemeldet werden müssen.
                     Es können bis zu 24 Variablen gleichzeitig
                     angemeldet sein.
                     Es müssen mindestens ein iname und ein oname
                     registriert sein. Bei einem iname sind weitere
                     Angaben im Argument möglich.
                     Eine Anmeldung kann eine Erstanmeldung oder eine
                     Wiederholungsanmeldung sein. Bei einer Erstanmeldung
                     wird  delim = 32:10:9:13:12:11  voreingestellt.
                     Das ist in anderer Notation:  ' \n\t\r\f\v'
                     Es handelt sich um die üblichen Zwischenraumzeichen.
                     Angaben im Argument können diese Voreinstellung ändern.
                     Ein zuletzt angegebenes iAnmelde-Argument setzt den dort
                     angegebenen iNamen aktiv.
                     Dabei können beliebig neue Daten mitgegeben werden.
                     Das Kommando arbeitet stets mit einem aktiven iNamen
                     und mindestens einem angemeldeten oNamen.
                        iname='  waw iut  ika   '
                     Aus dem vorstehenden Inhalt filtert das Kommando die
                     Wörter  waw|iut|ika  heraus und schreibt sie in drei
                     oVariablen hinein, wenn als Delimiter mindestens ein
                     Leerzeichen angegeben wurde und falls mindestens drei
                     oVariablen angemeldet sind.
                     Eine iVariable wird bis zur Länge ${#iname} gelesen.
                     Eine oVariable wird stets von Beginn an beschrieben.
                     Danach wird die Länge ${#oname} entsprechend gesetzt.
                     Eine Anmeldung bei bereits vorliegendem Angemeldetstatus
                     aktiviert lediglich, sofern dabei keine Parameterwerte
                     explizit angegeben sind:
                        d,iname
                        iname
                        ,iname
                     Wie zu sehen ist, werden die Parameter anhand der
                     Position ihrer Werte erkannt.
                     Die letzte Zeile zeigt eine _Abschaltung_ des
                     Delimiters  delim='', also einen leeren Delimiter.
                     In diesem Fall wird der gesamte Inhalt einer iVariable
                     in eine oVariable kopiert.
                     ---
                     Eine Abmeldung -name löscht den Zugriff,
                     falls es sich um einen aktiven Namen handelt!
                     Eine Abmeldung - meldet alle iNamen ab
                     und löscht den Zugriff.
                     Eine Abmeldung = meldet alle oNamen ab.
                     und löscht den Zugriff.
                     Eine Abmeldung -= oder =- meldet alle Namen ab
                     und löscht den Zugriff.
                     ---
                     Bei Aufruf von  spreadmv  ohne Argumente wird gelesen
                     und geschrieben.
                     Falls kein Delimiter in den gelesenen Daten gefunden
                     wird oder wenn der Delimiter abgeschaltet ist, wird
                     die iVariable in einem Zug vollständig gelesen.
                     Der Delimiter kann auf jeden Wert von 0..255
                     gesetzt werden, und zwar per Dezimalzahl oder durch
                     ein Zeichen ungleich den Ziffern '0'-'9'.
                     ---
                     Eine Delimiter-Angabe  12:34:56:78,  ist möglich.
                     Es können hier maximal 11 Delimiter angegeben werden.
                     Das Verhalten ist dahingehend, daß beliebig viele
                     Delimiter überlesen werden, bis Daten vorliegen, die
                     keine Delimiter sind und daher in eine oVariable
                     übertragen werden.
                     ---
                     Durch einen Aufruf »spreadmv« wird $. jeweils auf die
                     Anzahl der ausgefilterten und übertragenen Wörter gesetzt.
                     Gibt es in der iVariablen nur Delimiter, wird die erste
                     oVariable leer gesetzt, also ${#oname} = 0.
                     Die Zielvariablen werden durch  spreadmv  nicht
                     vergrößert, sie müssen vorher schon groß genug sein.
                     Die Größe der Zielvariablen ${#Z} variiert je nach
                     aktuell darin enthaltener Datenmenge/Zeilenlänge.
                     Eine Veränderung der internen Länge ${:Z} jedoch wird
                     bei bei  spreadmv  angemeldeten Variablen blockiert.
                     ---
                     Es ist der Gültigkeitsbereich lokaler Variablen
                     zu beachten!
                     spreadmv  erfährt es nicht, wenn angemeldete Variablen
                     durch andere Kommandos gelöscht oder verändert werden!
                     Allerdings informiert der Variablen-Manager  spreadmv
                     bei Änderung von Basiszeigern durch realloc().
                     ---
                     Vergleich spreadmv <> Shell <> bish <> bash:
                     --------------------------------------------
                     spreadmv:   0.62 real     0.62 user     0.00 sys
                     bish:       1.53 real     1.53 user     0.00 sys
                     Shell:     12.37 real    12.34 user     0.00 sys
                     bash:      52.34 real    52.18 user     0.00 sys
                     (Core2Duo/3333)
                     Um einen Faktor 20 schneller als gewöhnlicher Shell-Code
                     ist beeindruckend und wohl kaum zu überbieten.
                     Die normale bish-Lösung mit  for 5 a b c d e  ist mit
                     einem Faktor 2,5 langsamer erstaunlich schnell.
                     Die bash-Lösung, ausgeführt von /usr/local/bin/bash, wird
                     um einen Faktor 84 übertroffen!
                     Die bish ist hier bei gleichem Code 4,2-mal schneller als
                     die bash.
                     ---
                     Test-Script:
                     ------------
                        Spread()  {
                           local i='  weg urg  yiihoh qq   wusta '
                           local a:.10 b:.10 c:.10 d:.10 e:.10
                           spreadmv i =a =b =c =d =e 
                           to 1000000 repeat
                           do
                              spreadmv
                           done
                           return 0
                        }

                        Bish()  {
                           local i='  weg urg  yiihoh qq   wusta '
                           local a:.10 b:.10 c:.10 d:.10 e:.10
                           to 1000000 repeat
                           do
                              for 5 a b c d e in $i
                              do
                                 nop
                              done
                           done
                           return 0
                        }

                        Shell()  {
                           local i='  weg urg  yiihoh qq   wusta '
                           local a:.10 b:.10 c:.10 d:.10 e:.10
                           local n=1 w:.10
                           to 1000000 repeat
                           do
                              for w in $i
                              do
                                 case $n in
                                   1)  a=$w;;
                                   2)  b=$w;;
                                   3)  c=$w;;
                                   4)  d=$w;;
                                   5)  e=$w;;
                                 esac
                                 let "++n>5" && n=1
                              done
                           done
                           return 0
                        }

                        Bash()  {
                           i='  weg urg  yiihoh qq   wusta '
                           a=........... b=........... c=...........
                           d=........... e=...........
                           n=1 w=wwwwwwwww cnt=0
                           while let "++cnt<=1000000"
                           do
                              for w in $i
                              do
                                 case $n in
                                   1)  a=$w;;
                                   2)  b=$w;;
                                   3)  c=$w;;
                                   4)  d=$w;;
                                   5)  e=$w;;
                                 esac
                                 let "++n>5" && n=1
                              done
                           done
                           return 0
                        }
                     Kontrollausgabe:  echo "$.:$a:$b:$c:$d:$e:"
                     spreadmv:         5:weg:urg:yiihoh:qq:wusta:



      copymv  [quelle ziel]...                                (-Z-)
      copymv  {-|--}
      copymv         Arbeitsverwendung nach Namen-Anmeldung
      copymv         Kommando 1
      copymv1        Kommando 1
      copymv2        Kommando 2
      copymv3        Kommando 3
                     Dieses Kommando verfolgt das Konzept der dauerhaften
                     Speicherung von Variablen-Zugriffsstrukturen, so wie die
                     vorstehend beschriebenen Kommandos readmv, writemv,
                     spreadmv.
                     Es ist allerdings wegen seiner Aufgabe des Kopierens
                     wesentlich einfacher. Intern und auch in der Bedienung.
                     Hinsichtlich der dauerhaften Speicherung sind es drei
                     unabhängige Kommandos.
                     Vor dem Kopiervorgang (ohne Argumente) müssen ein bis
                     zwölf Paare von Variablennamen existierender Variablen
                     registriert werden:  copymv  q z  q z  q z  q z  q z
                     Zuvor gespeicherte Informationen werden dabei pauschal
                     überschrieben, und ungenutzter Restspeicher wird gelöscht.
                     Die Zielvariablen müssen bezüglich Länge ${:name} groß
                     genug sein. Bei diesen wird nach dem Kopiervorgang die
                     Inhaltslänge ${#name} angepaßt.
                     Durch ein Argument '-' wird der Speicher des aufgerufenen
                     Kommandos gelöscht. Ein Argument '--' löscht bei allen
                     drei Kommandos.



      casemv  suchmuster case-liste [liste ziel]...           (-Z-)
      casemv  {-|--}
      casemv         Arbeitsverwendung nach Namen-Anmeldung
      casemv         Kommando 1
      casemv1        Kommando 1
      casemv2        Kommando 2
      casemv3        Kommando 3
                     Dieses Kommando verfolgt das Konzept der dauerhaften
                     Speicherung von Variablen-Zugriffsstrukturen, so wie das
                     vorstehend beschriebene Kommando  copymv.
                     Kommando  casemv  ist ebenfalls ein Dreifach-Kommando:
                     Es gibt drei voneinander unabhängige Speichersätze.
                     Durch ein Argument '-' wird der Speicher des aufgerufenen
                     Kommandos gelöscht. Ein Argument '--' löscht bei allen
                     drei Kommandos.
                     Das Kommando stellt eine case..esac-Konstruktion in
                     völlig anderer Form dar:
                            case "suchmuster" in
                              a)  ...;;
                              b)  ...;;
                              C)  ...;;
                              D)  ...;;
                              *)  ...;;
                            esac
                     Vorstehend die bekannte Code-Form.
                     Nachfolgend die gleiche Aufgabe in einer Daten-Form:
                            suchmuster='sl5'
                            cases='32; slk4 sl5 fmk4 /fmk. fms3'

                            liste1='10,13;
                            slk4)echo kfurt:
                             sl5) fendar -jp
                            fmk4)foo; bar'

                            casemv suchmuster cases liste1 ziel1 liste2 ziel2
                            # ...
                            casemv && { $ziel1; eval $ziel2; }
                     Vorstehend würde ' fendar -jp' ausgeführt werden.
                     Es können bis zu 127 cases/Fälle aufgelistet werden.
                     Bis zu vier Paare  [ liste  ziel ]  sind möglich.
                     Jede Liste darf bis zu 65534 Byte groß sein.
                     Wenn das Suchmuster beispielsweise zum zweiten Eintrag in
                     der case-Liste paßt, wird der zweite Eintrag aus jeder
                     angemeldeten Paar-Liste in das jeweils zugehörige Ziel
                     kopiert.
                     Generell wird eine case-Liste in Einzelschritten von vorne
                     an durchlaufen. Jedoch wenn es keine Regulären Ausdrücke
                     gibt (s.u.), wird eine eventuelle Verlinkung auf das
                     Anfangszeichen durchlaufen, und wenn diese keinen Treffer
                     ergibt, wird auf einen Default-case geprüft.
                     Das Suchmuster ist das sich oft ändernde Element.
                     Dieser Variableninhalt kann nach jeder Änderung durch
                     Aufruf von  casemv  getestet werden.
                     In eine Paar-Liste können prinzipiell beliebig viele
                     Einträge aufgenommen werden.
                     Allerdings werden im Vergleich zur case-Liste überzählige
                     Einträge ignoriert, und umgekehrt können höher indexierte
                     Einträge in der case-Liste aus nicht vorhandenen korres-
                     pondierenden Einträgen in Paar-Listen nichts ins jeweilige
                     Ziel kopieren.
                     Die Zwischenraumzeichen/Trennzeichen/Delimiter können in
                     jeder Liste zu Anfang in Form von durch Kommata getrennte
                     Dezimalzahlen notiert werden. Abschluß dieser Zahlenkette
                     erfolgt durch ein Semikolon.
                     Ein Weglassen oder nur ein ; zu Beginn führen dazu, daß
                     keine Delimiter registriert werden. In solch einem Fall
                     besteht eine Liste aus nur einem Eintrag.
                     Es sind maximal 14 Delimiter möglich.
                     Jedem Eintrag in einer Paar-Liste muß eines der
                     Zeichen  ) :  vorangestellt sein.
                     Bis dahin können beliebige Notizen geschrieben werden, die
                     aus Nicht-Zwischenraumzeichen bestehen müssen.
                     Auch direkt dahinter darf kein Zwischenraumzeichen stehen.
                     Die beiden Zeichen  ) :  sollten logischerweise nicht als
                     Zwischenraumzeichen definiert werden.
                     Falls  suchmuster  bei der Anmeldung der Variablen genau
                     den Inhalt "note=none" hat, schaltet dies den Notizzwang
                     ab. Inhalt "note=note" schaltet ihn wieder ein.
                     Der jew. Zustand bleibt im laufenden bish-Prozeß erhalten.
                     Jedes Kommando 1,2,3 hat einen solchen Schalter.
                     ---
                     Einem Eintrag in der case-Liste kann ein Zeichen / voran-
                     gestellt werden, um einen Regulären Ausdruck zu
                     kennzeichnen:  /_[Rr]k.sa*
                     Das Zeichen / hat daher ein Spezialbedeutung in der
                     gesamten case-Liste.
                     Um ein gewöhnliches Zeichen / herzustellen, müssen zwei
                     davon (//) angegeben werden.
                     Um einen RA zu kennzeichnen, der zusätzlich /// als Inhalt
                     enthält, bedarf es /////// (sieben). Das sind drei Paare
                     und einen weiteren / zur Anzeige eines RA, also
                     eine _ungerade_ Anzahl.
                     Einem Eintrag in der case-Liste, der _keinen_ RA
                     repräsentieren soll, müssen gleichfalls Paare // voran-
                     gestellt werden, um je ein Zeichen / darzustellen, also
                     eine _gerade_ Anzahl von /.
                     Der Ausdruck  _[Rr]k.sa*  (s.o.) kann auch als gewöhnliche
                     Zeichenfolge verwendet werden, ohne einen einen RA
                     anzeigenden / davor.
                     Eine Angabe von Paaren (//) ist nur erforderlich, falls es
                     sich um _vorne_ stehende / handelt!
                     Ein Listeneintrag /// ist ein RA, der aus / besteht.
                     Ein Eintrag / ist ein _leerer_ RA, der zu allem paßt!
                     Dies ist also der Default-case.
                     (Intern wird dieser nicht als RA geführt!)
                     Auch .* ist ein RA, der zu allem paßt.
                     Eine leere case-Liste paßt ebenfalls zu allem!
                     Als RA werden BRE verwendet; Siehe expr(K).
                     ---
                     Das Kommando retourniert TRUE (0), bei einem zum Such-
                     muster passenden case-Listen-Eintrag oder einer passenden
                     case-Liste, andernfalls FALSE.
                     Die Inhalte von $. $. zeigen den Listenindex nach Finden
                     und denjenigen vom Eintritt in die Suche.
                     Den zweiten Zugriff auf $. nur per bish-Option -O.
                     Angemeldete Zielvariablen werden bei einem argumentlosen
                     Aufruf des Kommandos zu Beginn auf Länge ${#name} = 0
                     gesetzt. Ohne eine angemeldete Paar-Liste gibt es nur den
                     Exit-Code und den Inhalt von $. als Information.
                     ---
                     Umgang mit Zielvariablen:
                            a='echo aa bb'
                            $a cc
                            b='echo aa; echo $bb'
                            bb=BB
                            eval $b cc
                     funktionieren jeweils.
                     Das legt nahe, Funktionsnamen mit eventuellen Argumenten
                     in Zielvariablen kopieren zu lassen.
                     Die Kommandos  eval, run?  können aufwendiger sein.
                     ---
                     Das Kommando kann auch für beliebige Mapping-Zwecke
                     benutzt werden. Beispielsweise RGB-Daten (#AACCFF)
                     an Farbnamen zuordnen. Als Farbnamen können
                     z.B.  gelb Gelb GELB  verwendet werden. Für diese können
                     drei Fälle mit gleichen korrespondierenden Einträgen
                     in Paar-Listen gebildet werden.
                     Gegenüber RA hat dieses Konzept Geschwindigkeitsvorteile.
                     Eine case-Liste ohne RA wird verlinkt und ist unter
                     anderem dadurch ultraschnell.
                     Durch die bis zu vier Paar-Listen kann das Kommando
                     beliebig Code- wie auch Daten-Inhalte selektieren;
                     vertikal und horizontal.
                     Es ist geeigneter, vor der Verwendung eines Suchmusters
                     dieses z.B. per  conv  anzupassen, als einen Algorithmus
                     zum Ignorieren von Groß- und Kleinschreibung, für jeden
                     Fall individuell, in dieses Kommando einzuflechten.
                     ---
                     Vergleiche der Geschwindigkeit:
                     -------------------------------
                     bish:  0.39 real     0.39 user     0.00 sys
                     bish:  0.45 real     0.45 user     0.00 sys
                     bish:  0.67 real     0.66 user     0.00 sys
                     bash:  9.97 real     9.92 user     0.00 sys
                     cases='32; aaaa bb bbb bbbb ccc ddd e ee /   fff'  (1)
                     cases='32; aaaa bb bbb bbbb ccc ddd e ee /.* fff'
                     cases='32; aaaa /bb /\w[BCb]b bbbb /ccc ddd /e ee /.* fff'
                     bash mit normalem case..esac, gleiche cases (1)
                     ---
                     Die bash braucht 26-mal mehr Zeit, was nicht überrascht.
                     Testskript-Code bish:
                        set -fBO
                        casemv muster cases lista ziela listb zielb
                        muster='zkl'
                        casemv
                        echo $.,$.: ec=$? za=${#ziela} zb=${#zielb}
                        echo ":$ziela::$zielb:"
                        to 100 repeat
                        do
                           for m in aaa bbb sld ddd vil ffff
                           do
                              muster="$m"
                              to 1667 repeat
                              do
                                 casemv
                              done
                           done
                        done
                     Die Inhalte von lista und listb sind hier nicht gezeigt.
                     Die bish benötigt hier 390 Nanosekunden für eine einmalige
                     Erfüllung der Aufgabe. Das ist noch weniger als beim Test
                     des Kommandos  spreadmv (620 ns). Prozessor Core2Duo/3333.



      readc          Liest Tastendrücke und antwortet   (-Z-)
                     mit Strings oder Zeichen.
                     Siehe readc(K).


      list  [-fdoecpRF0]  [ dir [file ...] ]            (-Z-)
                     Listet Inhalte von Verzeichnissen.
                     Die Funktion ähnelt denen von 'ls -R' und 'dir /b/s'.
                     Es werden nur Namen oder Pfadnamen gelistet, also
                     keine weiteren Merkmale, wie Zeitstempel, etc.
                     -f     Nur normale Dateien werden gelistet.
                     -d     Nur Verzeichnisse werden gelistet.
                     -o     Alle Dateinamen, die nicht vom Typ -f und -d sind,
                            werden gelistet.
                            Die Optionen -f,-d,-o sind voreingestellt, falls
                            keine davon angegeben wird.
                     -e     Nur leere Verzeichnisse werden gelistet.
                     -c     Nur die Anzahl der Namen wird ausgegeben,
                            die Ausgabe der Namen wird unterdrückt.
                            Die Optionen -f,-d,-o werden berücksichtigt.
                     -p     Die Kommandoargumente werden mit den Namen
                            aus den Verzeichnissen zu Pfaden verkettet.
                     -R     Es wird rekursiv gesucht.
                            Option -p wird hierbei aktiviert.
                     -F     In Verbindung mit den Optionen -f,-d,-o
                            können die Argumente nach Typ gefiltert werden.
                            Sinnvoll bei Wildcard-Argumenten.
                            Mit dieser Option werden NUR die Kommando-
                            -argumente (teilweise) gelistet.
                     -0     Als Zeilenvorschub wird 0 ('\0') ausgegeben!
                            Dies nur bei isatty(1)==FALSE.
                            (Siehe Kommando 'readl')
                     Die Optionen müssen als einzelnes Argument angegeben
                     werden.
                     Die Anzahl der Namen wird in $. gespeichert.
                     Dieses Kommando ist nicht dafür da, um schöne, formatierte
                     Listen zu erzeugen, sondern um Daten zu gewinnen zur
                     Weiterverarbeitung. (s. DIR / ls -l)
                     Exit==FALSE, falls eine angegebene Datei nicht
                     existiert.


      sortl  [-r] [-f[nr]#[,[nr]#]...] [-d[c...]] [-D#] [-odatei]  [datei...]
                     Sortiert Textdateien zeilenweise.
                     -r     Kehrt die Sortierreihenfolge um. (reverse)
                     -f     Maximal 4 Feldnummern können angegeben werden,
                            nach denen sortiert wird.
                            Das zuerst angegebene Feld hat die höchste
                            Priorität, usw.
                            Voreinstellung:  -f1,2,3,4
                            Der Buchstabe 'n' bewirkt, daß das betreffende
                            Feld als Dezimalzahl bewertet wird.
                            'n' kann vor oder nach der Zahl stehen.
                            Die DOS-Version ignoriert 'n'!
                            'r' wirkt feldbezogen wie -r und zusammenwirkend
                            mit -r: reverse =  r != -r
                     -d     Angabe der Zwischenraumzeichen, die die
                            Felder abgrenzen. (delimiter)
                            Voreinstellung:  -d" TAB"
                            -d ohne nachfolgende Zeichen bedeutet, daß es
                            gar keine Trenner gibt.
                            In diesem Fall werden die Zeilen als ein
                            einziges Feld angesehen.
                     -D     Angabe des Zeilenende-Zeichens als Dezimalzahl.
                            Voreinstellung:  -D10
                     -o     Ausgabe erfolgt in die hier angegebene
                            Datei, nicht zur Standardausgabe.
                     Falls keine Datei angegeben ist, wird von der
                     Standardeingabe gelesen, jedoch nicht von einem
                     tty-Gerät.
                     Mehrere Dateien werden zusammengefaßt und
                     als eine Gesamtheit sortiert.
                     Dieses -interne- Kommando ist (aus diesem Grund)
                     in Teilbereichen relativ einfach konzeptioniert.
                     Es erwartet, daß alle Inhalte und die Steuerdaten zu
                     jeder Zeile komplett in den Arbeitsspeicher passen.
                     Zu jeder Zeile werden 64/32 Byte (Unix/Dos)
                     zusätzlich benötigt.
                     Das Kommando ist extrem schnell, etwa 2 Sekunden
                     bei 2 MByte:40000z  auf einem mittelschnellen PC,
                     einschließlich dem Schreiben der Ausgabedatei -
                     - etwa 6-fach schneller als 'sort'.
                     Unter DOS können Inhalte bis etwa 250 KB in
                     einem Stück sortiert werden. (DOS-sort: 64KB)
                     Darüber hinaus kann man ein kleines bish-Script
                     verwenden, das die Inhalte zerteilt und dann die
                     Teile vertikal+horizontal sortiert.
                     Kommandos dazu:  wc, mktemp, line, sortl, ...
                     Ein einzelnes Zeichen am Dateiende
                     nach dem letzten Zeilenvorschub wird von der
                     DOS-Version entfernt - das dürfte fast immer
                     ^Z sein, das sonst nach oben sortiert würde.


      findccc [-SAN0o_l_a_r_n_i_e_z_L_H_T_,-] quelle ausgabe zeilen
                            [k0 k1]...  [kz ke zv]... [z0 z1 zn zj zy mz]...
                     Findet in Quelltexten einer beliebigen Programmiersprache
                     Kommentare, Zeilenkommentare, Zeichenketten-Konstanten
                     und Zeilenvorschübe.
                     -S     Ausgabe von nur der festgestellten Ausgabelänge.
                     -A     Ausgabe hinter die vorliegende Länge ${#ausgabe}.
                     -N     Ausgabe von Zeilenvorschub-Daten wird aktiviert.
                     -0     Der Offset (-o#) wird _nicht_ zur jeweiligen
                            Startposition (s.u.) hinzuaddiert.
                     -o#    Angabe eines Offsetwertes für den Quelltext.
                            Voreingestellt ist 0.
                     -l#    Angabe einer Länge für den Quelltext ab Offset.
                            Voreingestellt ist Länge = Ende - Offset.
                     -a329  Angabe der Anzahlen von Kommentaren, Zeilen-
                            kommentaren und Zeichenketten.
                            Es kann jeweils 0..9 angegeben werden.
                            Voreingestellt sind 112.
                            Falls die Optionen  -anie  verwendet werden, muß
                            Option -a als erste davon angegeben werden.
                     -r201  Angabe der Reihenfolge der Abarbeitung der
                            Kommentar[1]-, Zeilenkommentar[2]- und
                            Zeichenketten[3]-Blöcke. Voreingestellt ist 123.
                            Die erste Ziffer bestimmt, welche Position[#]
                            als erste aufgesucht wird, usw.
                            Die Ziffer  0  führt dazu, daß auf der jeweiligen
                            Ziffernposition nichts gesucht wird, da es eine
                            solche Position[#] nicht gibt.
                     -n..-. Berücksichtigt verschachtelte Kommentare und
                            Zeichenketten (nested). Anwählbar per '.' und
                            abwählbar per '-'.
                            Es müssen so viele Zeichen [.-] angegeben werden,
                            wie Kommentare und Zeichenketten definiert sind.
                            Also {0..9}+{0..9} - maximal 18.
                            Für Zeilenkommentare ist eine Verschachtelung
                            nicht konfigurierbar.
                     -i..-. Groß- und Kleinschreibung wird nicht unterschieden
                            (insensitiv), gemäß Zeichensatz ISO8859-15.
                            Anzahlen {0..9}+{0..9}+{0..9} - maximal 27.
                     -e..-. Separiert beide Enden der Bereiche (s.u.).
                            Anzahlen {0..9}+{0..9}+{0..9} - maximal 27.
                            Separierung erfolgt nicht bei
                            einschachtelten Bereichen.
                     -z#    Ausgabe von Zeilennummern wird aktiviert (s.u.).
                            Gleichzeitig kann eine Start-Zeilennummer
                            angegeben werden. Voreinstellung ist 1.
                     -Labc  Der Bezeichner 'dat' wird hiermit überschrieben.
                            Länge maximal 10 Wort-Zeichen.
                     -Habc  Bezeichnervorsatz (Head).
                            Länge maximal 10 Wort-Zeichen.
                     -Tabc  Bezeichneranhang (Tail).
                            Länge maximal 10 Wort-Zeichen.
                     , -    Füll-/Trennzeichen in der Optionskette.
                            Beispiel:  -o23651-l243
                     Die Optionen müssen als ein einziges Argument
                     angegeben werden.
                     Für die Voreinstellung -a112 ist z.B. gültig:
                            -i..-.         .  .  -.
                              112          1  1  2
                     Drei Argumente, die jeweils einen frei wählbaren
                     Variablennamen enthalten:
                     quelle
                            Variable, die den Quelltext enthält.
                     ausgabe
                            Variable, in die Daten geschrieben werden.
                     zeilen
                            Variable, in die die Zeilenanzahl geschrieben wird.
                     Argumente ({0..9}*{2+3+6} <= 99), die je eine Zeichenfolge
                     enthalten:
                     k0     Startsequenz eines Kommentars.
                     k1     Endsequenz   eines Kommentars.
                     kz     Startsequenz eines Zeilenkommentars.
                     ke     Vorzeitig beendende Sequenz Zeilenkommentar,
                            optional, exklusiv, wie auch der Zeilenvorschub.
                            Wenn das erste Zeichen _kein_ Zwischenraumzeichen
                            ist, muß _vor_ der Sequenz ein solches stehen.
                     zv     Zeichen für Zeilenverlängerung Zeilenkommentar.
                     z0     Startsequenz einer Zeichenkette.
                     z1     Endsequenz   einer Zeichenkette.
                     zn     Zeichen, die nicht direkt vor einer
                            Zeichenkette stehen dürfen, -> Abbruch.
                     zj     Zeichen(folgen), die direkt vor einer
                            Zeichenkette stehen können.
                     zy     Zeichen, die direkt nach einer
                            Zeichenkette stehen können.
                     mz     Maskierzeichen oder Maskierzeichenfolge
                            in Zeichenkette.
                     Bei mehr als einem Maskierzeichen ist diese Folge nicht
                     beendend für die Zeichenkette (s.u.).
                     Mit Ausnahme des Optionsargumentes müssen alle Argumente
                     vorhanden sein.
                     Leere Argumente ('') (außer quelle, ausgabe) schalten
                     die jeweilige Funktion ab.
                     Anstelle von '' kann auch  vOId  verwendet werden.
                     Nämlich in einem Variableninhalt kann kein Leerargument
                     direkt dargestellt werden.
                     Falls z.B. Argument  z0  leer ist, werden alle damit
                     in Zusammenhang stehenden Argumente bis  mz  ignoriert.
                     Falls  mz  leer ist, entfällt nur dessen Funktion.
                     Bis auf die beendenden Sequenzen beim Zeilenkommentar
                     sind die Sequenzen und Zeichen inklusiv.
                     Zeichenfolgen-Argumente haben keine Längenbegrenzung!
                     Die Zeichen \r \n sollten nicht Bestandteil von solchen
                     Argumenten mit Bezug zur Quelle sein! Diese sind für das
                     Kommando die einzigen Zeichen mit Spezialbedeutung
                     in der Quelle.
                     Eine nicht existierende Variable 'zeilen' wird lokal
                     mit ausreichender Größe angelegt.
                       zn:   z.B. in C sind '"' und '\"' möglich!
                       zj:   z.B. in C sind   L u U u8   möglich!
                       zy:   z.B.  A W  sind nachgestellt möglich!
                       mz:   bekannt sind  \  und  ''.
                       Es handelt sich um eine Auswahl von Einzelzeichen.
                       Bei  zj  und  mz  sind auch bis zu 16 Zeichenfolgen
                       mit jeweils mehr als einem Zeichen möglich, getrennt
                       durch Zeilenvorschübe oder benachbart von einem
                       Zeilenvorschub (zj). Ein erkannter Zeilenvorschub
                       schaltet den Einzelzeichenauswahl-Modus ab:
                       Ein Inhalt:  \n\nL\r\ru\nU\nu8   (L u U u8)
                       Die Zeichen \r und/oder \n dürfen beliebig zwischen
                       und neben den Zeichenfolgen angeordnet sein.
                       Eine Reihenfolge sollte  kf f  statt  f kf  sein,
                       damit  f  nicht  kf  abfängt. Siehe Kommando  findcs.
                     Variable 'ausgabe' muß bei Option -S wenigstens 25 Byte
                     groß sein. Ohne Option -S kann eine Größe von vielen MB
                     notwendig sein. Das ist vom Quelltext und von Optionen
                     abhängig. Die notwendige Größe ist oft etwa ein Siebtel
                     der Quelle.
                     Kommando  findccc  vergrößert Variable 'ausgabe' NICHT!
                     Das Management extrem großer Variablen ist besser von
                     außen zu überblicken. (Siehe set, local, unset)
                     Es wird maximal bis zur Länge ${:ausgabe} geschrieben
                     und danach die Länge ${#ausgabe} angepaßt.
                     Die Datenausgabe besteht aus folgenden Folgen von je drei
                     Zeichenfolgen:
                            dat  startposition länge
                            ko1  startposition länge ...
                            ko9  startposition länge
                            kz1  startposition länge ...
                            kz9  startposition länge
                            zk1  startposition länge ...
                            zk9  startposition länge
                            ko1s startposition länge ...
                            ko9s startposition länge
                            ko1e startposition länge ...
                            ko9e startposition länge
                            kz1s startposition länge ...
                            kz9s startposition länge
                            zk1s startposition länge ...
                            zk9s startposition länge
                            zk1e startposition länge ...
                            zk9e startposition länge
                            lf   startposition länge
                            ln   zeilennummer  länge
                     dat    Daten allgemein (Rasen)
                     ko#    Genereller Kommentar
                     kz#    Zeilen-Kommentar
                     zk#    Zeichenkette
                     ??#s   Startsequenzen (nicht eingeschachtelt)
                     ??#e   Endsequenzen   (nicht eingeschachtelt)
                     lf     Zeilenvorschub
                     ln     Zeilennummer mit deren Länge
                     Die Ausgabe kann per Schleife ausgewertet werden:
                            for 3 label start length in $ausgabe ...
                            catv offs,len,quelle ...
                     Das typisch nachfolgende Kommando ist:  findcs
                     Kommando  expr  kann weitere Aufgaben übernehmen.
                     Zeilenvorschübe \n und \r\n gemischt werden verarbeitet.
                     Bei vorliegendem \r muß zuvor per Kommando 'tr' oder
                     Editor 'vim' oder anderen Werkzeugen die Quelle
                     konvertiert und/oder repariert werden.
                     Wenn eine ungerade Anzahl von Maskierzeichen vor einer
                     Endsequenz steht, wird die Zeichenkette hier nicht
                     beendet. Bei mehr als einem angegebenen Maskierzeichen
                     wird bei antreffen einer solchen Folge in der Zeichenkette
                     fortgefahren. Beispiel: 'abc''def'  ('').
                     Exit-Code:  1       Argumente
                                 2       Variablen
                                 3       Variable quelle
                                 4       Limits Argumente
                                 6       Bereich nicht geschlossen
                                 10..38  Ausgabe a  (label, wert)
                                 40..68  Ausgabe b  (2. wert)
                     Exit-Werte >0 werden von Fehlermeldungen begleitet.
                     Es gibt hier nur einen Abbruch des Kommandos.
                     Exit=6 ist nur eine Information - ohne Abbruch.
                     ---
                     Dieses Kommando  findccc  ist ein Anfangspunkt
                     beispielsweise zur Herstellung von Syntax-Highlighting.
                     Die gelieferte Anzahl Zeilen z.B. hilft bei der Festlegung
                     der notwendigen Füllzeichen vor Zeilennummern.
                        set -fB
                        set src:' 1000000' out:' 10000' lines:020
                        catv 0 =src: <./modules/grase.c
                        findccc src out lines /* */  // '' \\  \
                                              \" \" "\'" LuU '' \\  \
                                              \' \' ''   LuU '' \\
                        ec=$?
                        catv out /:\n
                        echo "exit=$ec" ${:src} ${:out} ${#src} ${#out} $lines
                     Vorstehend ein Beispiel mit folgender Ausgabe:
                        ko1 0 72       dat 699 15     dat 923 36
                        dat 72 4       zk2 714 3      zk2 959 3
                        kz1 76 60      dat 717 144    dat 962 36
                        lf 136 2       zk2 861 3      zk2 998 3
                        dat 138 454    dat 864 17     dat 1001 36
                        zk2 592 3      ko1 881 19     zk2 1037 3
                        dat 595 101    dat 900 20     dat 1040 36
                        zk2 696 3      zk2 920 3      zk2 1076 3
                        exit=0 1000000 100000 11948 1593 12 328
                     Hier wurde Zeichenkette2 für Zeichenkonstanten 'x' in C
                     benutzt. Das vergrößert die Ausgabe beträchtlich.
                     Die Größe ist etwa ein Siebtel der Quelle.
                        ln 1 1         lf 89 2        ln 6 1
                        ko1 0 72       ln 4 1         dat 138 46
                        lf 72 2        kz1 91 1       lf 184 2
                        ln 2 1         lf 92 2        ln 7 1
                        lf 74 2        ln 5 1         dat 186 60
                        ln 3 1         kz1 94 42      lf 246 2
                        kz1 76 13      lf 136 2       ln 8 1
                     Für vorstehende Ausgabe wurden die Optionen -Nz gegeben.
                     Die Ausgabe ist dabei etwa gleich groß mit der Quelle.
                     ---
                     Zeilenvorschübe (lf) sind ausdrücklich isoliert, mitunter
                     auch ohne Option -N. Option -z erzwingt als Nebeneffekt
                     viele 'lf'. Ohne Option -N sind Zeilenvorschübe generell
                     in allen Bereichen enthalten, wobei in Zeilenkommentaren
                     dies nur bei Zeilenverlängerung vorkommt.
                     Für ein Syntax-Highlighting sind Zeilenvorschübe ohne
                     Bedeutung, da dies keine abdruckbaren Zeichen sind.
                     ---
                     Es können für einen Kommentar z.B. die Sequenzen
                            dätö>   <dätö
                     angegeben werden, und in der Quelle werden dann
                            DäTÖ>...<dÄtö
                     gefunden, falls -i zielgerichtet gesetzt ist.
                     Ist auch Option -e entsprechend gesetzt, dann wird z.B.
                            ko4s 90 5
                            ko4 95 244
                            ko4e 339 5
                     ausgegeben. Ein leerer Kommentar (ko4 95 0) würde hier
                     nicht ausgegeben, sondern unterdrückt.
                     Dies ist insgesamt ein Hinweis auf die hochgradige
                     Universalität dieses Kommandos  findccc.
                     Unter den Titeln Kommentar, Zeilenkommentar und
                     Zeichenkette müssen auch keine Kommentare, Zeilen-
                     kommentare und Zeichenketten gesucht werden, sondern
                     einfach irgendwelche Bereiche mit irgendwelchen
                     Start- und Endsequenzen.
                     Die Zeichen \n \r können auf mehrere Arten in eine
                     Variable eingefügt werden:
                            mz='u8       set nl:10.1 cr:13.1
                            L            mz="u8${nl}L${nl}u${nl}U"
                            u
                            U'
                            mz=u8,L,u,U ; conv "-t,$nl" mz
                     Auch Kommando  expr  stellt Wege zur Verfügung.
                     ---
                     Im Regelfall können jeweils mehrere Argumente in eine
                     Variable geschrieben werden, um den Argumente-Wust besser
                     zu bewältigen. Anordnungen mit Zeilenverlängerung sind
                     jedoch bereits akzeptabel.
                     Maximal sind über 100 Argumente erforderlich. Das ist
                     keine Übertreibung. Beispielsweise ein Shell-Programm
                     hat die Bereiche:
                            '__________'
                            "__________"
                            `__________`
                           $(__________)
                           ((__________))
                          $((__________))
                     Neben diesen Bereichen mit Start- und Endsequenz gibt es
                     viele weitere. So können Bereiche in größeren Bereichen
                     enthalten sein und dort bestimmte Unterschiede zugeteilt
                     erhalten.


      findcs [-SAcp1rdwRDW0o_l_L_H_T_,-]  quelle  zeichenfolgen  ausgabe
                     Findet in einer Datenquelle Zeichenfolgen, die in
                     bis zu 99 Gruppen eingeteilt werden können. Es sind
                     maximal 25000 Zeichenfolgen angebbar. Eine Zeichenfolge
                     darf maximal 255 Zeichen enthalten. Eine Gruppe hat eine
                     maximale Größe von 65535 Zeichen inklusive Trennzeichen.
                     Es wird nach feststehenden Zeichenfolgen gesucht, wie
                     beispielsweise Schlüsselwörtern. Eine Vorstufe von
                     Regulären Ausdrücken ist allerdings auch implementiert.
                     -S     Ausgabe von nur der festgestellten Ausgabelänge.
                     -A     Ausgabe hinter die vorliegende Länge ${#ausgabe}.
                     -c     Invertiert die contained-Funktion bei der
                            Konfiguration für eine Gruppe.
                            Der Modus-Buchstabe c ist nun eine Abschaltung.
                     -p     Ausgabe aller Zeichenfolgen. Diese können durch
                            eine aktive contained-Funktion umgeordnet sein.
                     -1     Die Quelle wird pauschal mit einer Schrittweite
                            von einem Zeichen durchlaufen.
                            Es wird angenommen, daß kein Rasen vorhanden ist.
                            Dies ist kaum sinnvoll bei den Optionen -dwDW.
                     -r     Modus 'raw', bei dem die Übergänge zur gefundenen
                            Folge unbeachtet bleiben.
                     -d     Modus 'wort+zwrm', bei dem zweimal vier Übergänge
                            berücksichtigt werden.
                     -w     Modus 'wort', bei dem zweimal zwei Übergänge
                            berücksichtigt werden.
                     -R     Wie -r.
                     -D     Wie -d, aber Übergangsgleichheit wird verlangt.
                     -W     Wie -w, aber Übergangsgleichheit wird verlangt.
                     -0     Der Offset (-o#) wird _nicht_ zur jeweiligen
                            Startposition (s.u.) hinzuaddiert.
                     -o#    Angabe eines Offsetwertes für den Quelltext.
                            Voreingestellt ist 0.
                     -l#    Angabe einer Länge für den Quelltext ab Offset.
                            Voreingestellt ist Länge = Ende - Offset.
                     -Labc  Der Bezeichner 'dat' wird hiermit überschrieben.
                            Länge maximal 10 Wort-Zeichen.
                     -Habc  Bezeichnervorsatz (Head).
                            Länge maximal 10 Wort-Zeichen.
                     -Tabc  Bezeichneranhang (Tail).
                            Länge maximal 10 Wort-Zeichen.
                     , -    Füll-/Trennzeichen in der Optionskette.
                            Beispiel:  -Latyp,o23657-l243,1
                     Die Optionen müssen als ein einziges Argument
                     angegeben werden.
                     Bei Option -p wird Argument 'quelle' nicht benutzt:
                     Das Argument muß vorhanden sein, aber in beliebiger Form.
                     Bei Option -S muß die 'ausgabe' 290 (-p) bzw. 30 Zeichen
                     Platz bieten.
                     Drei Argumente, die jeweils einen frei wählbaren
                     Variablennamen enthalten:
                     quelle
                            Variable, die die Quelldaten enthält.
                     zeichenfolgen
                            Variable, die bis zu 99 Variablennamen enthält.
                            Diese enthaltenen Namen bezeichnen Variablen, die
                            die Zeichenfolgen jeweils einer Gruppe enthalten.
                     ausgabe
                            Variable, in die Daten geschrieben werden.
                            Siehe Option -S.
                     Kommando  findcs  vergrößert Variable 'ausgabe' NICHT!
                     Das Management extrem großer Variablen ist besser von
                     außen zu überblicken. (Siehe set, local, unset)
                     Es wird maximal bis zur Länge ${:ausgabe} geschrieben
                     und danach die Länge ${#ausgabe} angepaßt.
                     ---
                     Die bis zu 99 Namen in 'zeichenfolgen' können im Rahmen
                     der Namenskonventionen prinzipiell beliebig gebildet
                     werden, unter Beachtung der nachfolgend beschriebenen
                     Bedeutungen.
                     Es können ein Bezeichner und ein Modus per Namensteil
                     für jede Gruppe definiert werden:
                            __nnnn_bbb_mm
                     Die Unterstrichlöcher  n_b  und  b_m  identifizieren
                     Bezeichner (b) und Modus (m).
                     Führende  _n  gelten nicht als Unterstrichloch.
                     Es können jeweils mehr als ein _ hintereinander
                     angegeben werden.
                     Die Längen für Bezeichner und Modus betragen
                     jeweils 1 bis maximal 10 Zeichen.
                     Fünf Modus-Zeichen(mengen) sind festgelegt:
                        Modus   Modus-Variation   Schalter
                            r     l     k     i     c
                            d     r     K     I     0
                            w     L     0     w
                            R     R           W
                            D     0           0
                            W
                            0
                     Das Zeichen  0  ist ein Auslassungszeichen.
                     Bei fehlendem Modus wird eine der Optionen -rdwRDW
                     verwendet oder letztlich der Modus  d  eingesetzt.
                     Die Zeichen  l r  sind Abkürzungen von links und rechts
                     und bedeuten, daß nur links oder nur rechts ein Übergang
                     geprüft wird (Anfang und Ende der Zeichenfolgen).
                     Normalerweise werden beide Übergänge geprüft.
                     Bei  L R  werden links bzw. rechts die Übergänge normal
                     geprüft; Zusätzlich werden die Übergänge rechts bzw. links
                     auf Gleichheit geprüft, wie bei den Modi  D W  generell.
                     Das dritte Zeichen wählt eine Zeichenklassen-Funktion.
                     Das vierte Zeichen wählt die Wort-Zeichenklasse (s.u.):
                            iI: ISO8859-15,  wW: ASCII.
                     Für Modus  d  ist  i  voreingestellt, ansonsten w.
                     Bei  I  und  W  wird zusätzlich zwischen Klein- und
                     Großschreibung nicht unterschieden, gemäß ISO8859-15.
                     Ein fünftes Zeichen  c  schaltet die contained-Funktion
                     selektiv nur für die Gruppe ein. Durch Option -c wird
                     diese Einschaltung invertiert und zu einer Abschaltung.
                     Der Modus  R  und  lrLR  für die Modi  rR  sind nur aus
                     Symmetriegründen vorhanden.
                     ---
                     Bei fehlendem Bezeichner wird ein Bezeichner
                     generiert:  s01 .. s99
                     Der Bezeichner  dat  wird für alle Bereiche in der Quelle
                     verwendet, die nicht mit einer gefundenen Zeichenfolge
                     zusammenfallen.
                     Modus-Angaben in der Gruppe per Namensteil
                     haben Vorrang vor den globalen Optionen -rdwRDW.
                     ---
                     Bei Modus  r  wird eine in der Quelle passende
                     Zeichenfolge unmittelbar als Fund anerkannt.
                     Bei den Modi  dwDW  erfolgt jeweils eine weitere Prüfung:
                       Es werden die Übergänge vom ersten Zeichen der Folge
                       zum Zeichen davor und vom letzten Zeichen der Folge
                       zum Zeichen dahinter geprüft:
                            d    ( !wort <- wort |  wort <- !wort |
                                   !zwrm <- zwrm |  zwrm <- !zwrm ) &
                                 ( !wort -> wort |  wort -> !wort |
                                   !zwrm -> zwrm |  zwrm -> !zwrm )
                            D    (  wort <- wort | !wort <- !wort |
                                    zwrm <- zwrm | !zwrm <- !zwrm ) &
                                 (  wort -> wort | !wort -> !wort |
                                    zwrm -> zwrm | !zwrm -> !zwrm )
                            w    ( !wort <- wort |  wort <- !wort ) &
                                 ( !wort -> wort |  wort -> !wort )
                            W    (  wort <- wort | !wort <- !wort ) &
                                 (  wort -> wort | !wort -> !wort )
                       Wort-Zeichen:  A..Z a..z _ 0..9
                       Zwrm-Zeichen:  blank \t \r \n \f \v  (Rasen)
                       Für Modus  d  gelten alle Wort-Zeichen des ISO8859-15.
                       Am Anfang und Ende der Datenquelle kann kein Übergang
                       geprüft werden:  Der Übergang ist stets zutreffend.
                     Die Funktionen  k K  sind jeweils eine Vorstufe eines
                     Regulären Ausdrucks:
                            k       4,3;cccc76543210
                            K     kn4,3;cccc76543210
                            K    .cn4,3;cccc76543210
                     Es wird durch eine Dezimalzahl (4) angegeben, wie viele
                     Zeichen nachfolgend als feststehende Zeichenfolge (cccc)
                     verglichen werden sollen (Präfix).
                     Nach  cccc  folgt eine beliebige Zeichenmenge, zu der
                     Zeichen aus der Quelle passen können.
                     Es muß also in der Quelle  cccc  passen, und nachfolgend
                     passen Zeichen, die in der angegebenen Menge (nach cccc)
                     enthalten sind.
                     Die Dezimalzahl  ,3  ist optional und gibt die maximale
                     Anzahl der zu den Zeichenklassen passenden Zeichen an.
                     Das Trennzeichen  ;  muß vorhanden sein;
                     Es wird pauschal übersprungen.
                     Beispiel:  2;0x0123456789ABCDEFabcdefuU
                            Bei 0;01 gibt es keinen Präfix.
                            Bei 2;0x gibt es nur den Präfix.
                     Ignorieren von Groß- und Kleinschreibung bezieht sich
                     auf den Präfix und die Einzeichenzeichenklasse (.c).
                     Bei Funktion  K  ist  kn  ein Zeichenpaar aus Klassen-
                     bezeichner (k) und Anzahlangabe (n).
                     In der Folge  .c  ist der Punkt eine Anzeige, daß ein
                     Einzelzeichen folgt - eine Einzeichenzeichenklasse (c).
                     Es sind bis zu 50 Folgen  kn  und/oder  .cn  möglich!
                     Für die Angabe der Anzahl (n) steht die
                     Zeichenmenge  ? + * 0 1 2 3 4 5 6 7 8 9  bereit:
                            ?       0 oder 1 Zeichen
                            +       1 Zeichen mindestens
                            *       beliebig viele Zeichen
                            0-9     absolute Anzahl (nur eine Ziffer!)
                     Die Klassen-Bezeichner (k):
                            w       A-Z a-z 0-9 _
                            B       A-Z a-z 0-9
                            h       A-Z a-z _
                            k       A-Z 0-9 _
                            a       A-Z a-z
                            u       A-Z
                            l       a-z
                            x       0-9 A-F a-f
                            d       0-9
                            o       0-7
                            s       [ \t\r\n\f\v]
                            b       [ \t]
                            g       [!-~]
                            p       . ,
                            v       + -
                     Die Bezeichner  W H A U L X D O S  für inverse Klassen
                     sind zusätzlich wählbar.
                     Beispiel:  h1w*0;
                            für gewöhnliche Namen, die nicht mit Ziffern
                            beginnen dürfen. Kein Präfix, keine
                            Suffixzeichenklasse.
                     Für die Suffixzeichen (s.o. 76543210) gilt implizit
                     die Anzahl '*'.
                     Bei Funktion  K  werden nacheinander Präfix, die Klassen,
                     und die selbstdefinierte Klasse (Suffix) auf ein Passen
                     getestet, soweit vorhanden.
                     Beispiel:
                            float_FLT_d0KW='
                            d*..1d+.e1v?d+0;flFL
                            d+..1d*.e1v?d+0;flFL
                            d+.e1v?d+0;flFL
                            d*..1d+0;flFL
                            d+..1d*0;flFL'
                     Für Floating-Point-Konstanten in C:
                     Von  123.456e-11L  bis  123.  und  .123f
                     ---
                     Modus  r  ist günstig, weil absolut alles gefunden werden
                     kann, das paßt. Fast egal, welche Zeichen beteiligt sind.
                     Außerdem entfällt bei  r  die Prüfung der Übergänge.
                     Begünstigt wird Modus  r  durch die contained-Funktion:
                     Diese sorgt dafür, daß keine zu suchende Zeichenfolge
                     Bestandteil einer nachfolgenden Zeichenfolge sein kann!
                     Dies geschieht nötigenfalls durch Positionsänderungen
                     intern innerhalb einer jeweiligen Gruppe.
                     Die Reihenfolge der Folgengruppen kann ebenfalls
                     entscheidend sein.
                     Nachfolgend eine Ausgabe dieses Kommandos  findcs:
                          uvb 11588 1       uvb 11596 1       uvb 11606 1
                          dat 11589 1       dat 11597 1       dat 11607 1
                          uvb 11590 2       uvb 11598 2       uvb 11608 1
                          dat 11592 4       dat 11600 6       dat 11609 9
                     Das Kommando  findccc  erzeugt die gleiche Ausgabe:
                            bezeichner  startposition  länge
                     Dieses Kommando  findcs  kann typischerweise nachfolgen,
                     indem eine Ausgabe  dat 23766 243  weiter bearbeitet
                     wird:  findcs -o23766-l243 ...
                     Die Arbeit von  findcs  kann Kommando  expr  fortsetzen,
                     das ebenfalls  expr 23766:243variable ...  Offset und
                     Länge entgegennehmen kann.
                     Alle diese Kommandos verarbeiten dieselbe Quelle readonly.
                     Exit-Code:  1       Argumente
                                 2       Variablen
                                 3       Variablennamen
                                 4       Unerwartetes null-Zeichen
                                 5       Modus-Angabe
                                 6       Limits
                                 7       Funktionen k K
                                 9       Ausgabe-Variable zu klein
                     Exit-Werte >0 werden von Fehlermeldungen begleitet.
                     Es gibt jedoch nur einen Abbruch des Kommandos.
                     ---
                     Nachfolgend ein Test-Skript mit Ausgaben:
                        set -fB
                        [ $# -eq 0 ] && exit
                        set src:' 1000000' out:' 100000'

                        oper_uvb_d='( ) [ ] -> . ++ -- (typ) ! ~ 
                        sizeof _Alignof (typ){} * / % + - { }
                        << >> < <= > >= == != & ^ | && || ? : .*
                        = += -= *= /= %= &= ^= |= <<= >>= ,
                        ??= ??( ??/ ??) ??'' ??< ??! ??> ??-
                        # ## ; ... <: :> <% %> %: %:%:'

                        typ_war_r='int32_t uint32_t'

                        str='oper_uvb_d typ_war_r'

                        catv 0 =src: <./modules/grase.c
 
                        findcs -p src str out
                        ec=$?
                        echo $ec ${:src} ${#src} ${:out} ${#out}

                        [ $ec -eq 0 ] && catv out /:\n

                     Die erste Ausgabe gehört zu den Optionen -pc :

                        oper_uvb_d='( ) [ ] -> . ++ -- (typ) ! ~ sizeof
                        _Alignof (typ){} * / % + - { } << >> < <= > >= == !=
                        & ^ | && || ? : .* = += -= *= /= %= &= ^= |= <<= >>=
                        , ??= ??( ??/ ??) ??' ??< ??! ??> ??- # ## ; ... <: :>
                        <% %> %: %:%:'
                        typ_war_r='int32_t uint32_t'

                     Die zweite Ausgabe gehört zu der Option -p :

                        oper_uvb_d='(typ){} (typ) [ ] -> .* ++ -- ??( != ~
                        sizeof _Alignof ??) *= /= %= += -= { } <<= >>= <= <<
                        >= >> == ??! && ^= || &= |= ??= <: ... = + ??- * ??/
                        <% & ^ | ??< ??> , ??' ( / ) ? < ! :> - ## # ; . %:%:
                        %> %: > : %'
                        typ_war_r='uint32_t int32_t'

                     Hier wurden einige Zeichenfolgen durch die aktive
                     contained-Funktion umgeordnet, damit keine Folge in einer
                     nachfolgenden Folge enthalten ist.
                     Dies ist gewöhnlich nur bei Modus  r  notwendig.
                     Natürlich geschieht eine Umordnung nur intern!
                     Vorstehend wird das Zeichen ' in einer Folge verwendet.
                     Siehe oben, erst  ??''  dann  ??'
                     In Shell-Skripten muß  '.....'.....'  in geeigneter
                     Weise repariert werden, abhängig vom Shell-Programm.



      remove [-RcsvV]  datei|dir ...                    (-Z-)
                     Löscht Dateien, Verzeichnisse, Verzeichnisinhalte
                     und Verzeichnisbäume - und Links.
                     -R     Löscht rekursiv.
                     -c     Löscht alle Dateien aus einem Verzeichnis.
                            Kann mit -R kombiniert werden.
                     -s     Unterdrückt Fehlermeldungen.
                     -v     Zeigt alle Aktivitäten.
                     -V     Zeigt alle Aktivitäten, jedoch ohne eine
                            konkrete Dateioperation vorzunehmen.
                     Die Optionen müssen als ein einziges Argument
                     angegeben werden.
                     Exit-Code:  1     Bei harmloseren Fehlern.
                                 2,4   Bei Fehler von System-Funktion
                                       und anderen Fehlerhaftigkeiten.
                     Fehler führen meist zu einem Abbruch.
                     Fehlgeschlagenes Löschen wird z.B. toleriert.
                     (Siehe auch 'link')


      move [-svVc]  datei|dir ...                       (-Z-)
                     Umbenennt Dateien oder Verzeichnisse
                     oder bewegt Dateien und/oder Verzeichnisse
                     in ein Zielverzeichnis hinein.
                     -c     Verschiebt nur alle Dateien aus einem
                            Verzeichnis in ein anderes. (Content)
                            Andernfalls werden Quellverzeichnisse
                            rekursiv bearbeitet.
                     Optionen -svV:  siehe remove-Kommando.
                     Bei Nichtexistenz des Zieles wird umbenannt,
                     wobei daraus auch eine Verschiebung resultieren darf.
                     Basisnamen der Quellobjekte werden an den Pfadnamen
                     eines existenten Zielverzeichnisses angehängt.
                     Bei mehr als zwei Dateiargumenten muß das letzte
                     ein Verzeichnis sein.
                     Wann immer es möglich ist, werden die Objekte
                     umgelinkt, das heißt es werden nur die
                     Verzeichniseinträge umgeschrieben, nicht aber
                     die Inhalte kopiert und anschließend gelöscht.
                     Das geht sehr schnell und vermeidet Fragmentierung,
                     ist aber laufwerkübergreifend nicht möglich.
                     Unter DOS können Verzeichnisse nicht umgelinkt werden,
                     wohl aber Dateien einzeln.
                     Unter Unix können Spezialdateien (c,b,p,m,s,l)
                     nicht filesystem-übergreifend behandelt werden.
                     Optionen -svV und Exit-Code:  siehe remove-Kommando.
                     Besonderheiten (SubPfad):
                          move  /a/b  /a/b/c
                          move  /a/b/c  /a/b
                     Relative Pfade ( ./ppp  ../ppp  ppp ) werden
                     komplettiert, jedoch nicht vollständig bei mehrfachem
                     relativen Bezug:
                          ../../../ppp/./qqq/../rrr
                     Falls so etwas angegeben wird, dann bitte genau
                     gleichsinnig, damit Pfad-Gleichheit und Sub-Pfade
                     erkannt werden können.
                     Bei mehreren Quellen dürfen unterschiedliche
                     Dateitypen vorliegen. Dabei muß jedoch mit
                     unvermutetem Verhalten gerechnet werden.
                     Am besten gibt man in solchen Fällen zunächst
                     einmal die Option -V an, um sich das Verhalten
                     zu betrachten.


      copy [-RmosvV]  datei|dir ...                     (-Z-)
                     Kopiert Dateien und/oder Verzeichnisse.
                     Ein Zielverzeichnis wird nötigenfalls erzeugt.
                     -R     Kopiert rekursiv.
                            Andernfalls werden nur die Dateien
                            eines Quellverzeichnisses berücksichtigt.
                     -m     Die Dateizeit wird 'mitkopiert',
                            andernfalls erhält das Ziel die aktuelle Zeit.
                     -o     User- und Gruppen-ID werden 'mitkopiert'.
                            (Nur unter Unix sinnvoll.)
                     Unter Unix können Spezialdateien (c,b,p,m,s,l)
                     nicht behandelt werden.
                     Optionen -svV und Exit-Code:  siehe remove-Kommando.
                     Siehe auch move-Kommando.


      mkdirs [-svV]  dir...                             (-Z-)
                     Erzeugt ein oder mehrere Verzeichnisse
                     pro Argument.
                     Beispielsweise  aaa/bbb/ccc/ddd  wird auf einmal
                     angelegt, soweit Nichtexistenz vorliegt.
                     Optionen -svV und Exit-Code:  siehe remove-Kommando.


      link  [-s]  pfad neuer_pfad ...                   (-Z-)
                     Erzeugt einen oder mehrere Links (Verweisnamen)
                     oder Symbolische Links (Option -s),
                     basierend auf 'pfad'.
                     Neue Pfade dürfen nicht bereits existieren.
                     (nur Unix)
                     Es werden nur Verzeichniseinträge hergestellt,
                     die auf die richtige Datei (mit Inhalt) verweisen.
                     Symbolische Links sind winzige Spezialdateien,
                     die auch auf Verzeichnisse und dateisystem-
                     -übergreifend verweisen können.


      seek  [:][+-][zahl]  [handle [name]]              (-Z-)
                     Ändert die Position eines Datei-Zeigers
                     oder zeigt eine Position an.
                     Verwendet wird eine Dateinummer (handle) einer
                     geöffneten Datei. Voreingestellt ist 0.
                     Die Dateinummer sollte nicht mit einem Gerät verknüpft
                     sein, da diese nicht 'seekable' sind.
                     ---
                     Verknüpfungen können mit globalen Umlenkungen
                     hergestellt werden, die in etwa einer Dateiöffnung
                     mittels 'open()' entsprechen.
                     ---
                     Wenn keine 'zahl' angegeben wird, erfolgt nur eine
                     Positionsmeldung auf die Standard-Ausgabe
                     oder aber in die Variable 'name'.
                     Eine angegebene Variable 'name' wird stets auf
                     (abschließende oder temporäre) Ist-Position gesetzt.
                     ---
                     Bei Angabe von '+' oder '-' wird relativ zur aktuellen
                     Position bewegt.
                     Der Doppelpunkt ':' symbolisiert das Dateiende als
                     Referenzpunkt.
                     Ohne ':+-' ist der Dateianfang der Bezugspunkt.
                     Mit dem ':' allein kann übrigens die Dateigröße
                     festgestellt werden:  seek : <datei; seek : 0 p <datei
                     'handle' wird ggf. als zweites Argument erwartet,
                     bei 'name' muß auch ein handle-Argument vorhanden sein.
                     Exit ist FALSE bei fehlgeschlagenem seek.
                     WARNUNG:
                     Anstelle von
                          pos=`seek + 1`   oder   pos=$(seek arg 1)
                     unbedingt
                          seek + 1 pos
                     verwenden! (wegen: handle 1 und `...`) 
                     ---
                     Wurde das Handle mit BlockMode geöffnet
                     (s.o. Umlenkungen: B<...),
                     so bedeutet beispielsweise '+ 1', daß der Filepointer
                     nicht um ein Byte, sondern um einen Sektor (512 Byte)
                     bewegt wurde.
                     Auf diese Weise können bis 1 TeraByte erfaßt werden.
                     Dabei:  Lesen und Schreiben nur mit n=x*512 !
                     ---
                     bish64 arbeitet direkt mit 64Bit breiten Zahlen.


      catv  [quelle(n) ...]  [=ziel]                       (-Z-)
            [[offset,]max,]objekt ...     objekt=name|handle
            [:+-][offset][:+-]
            [:.]objekt[:.]
            /konstante
            /abc%x%255xyz
            .konstante
            , ,. ,r
                     Dieses Kommando ist neben 'expr' und 'grep' mit ihren
                     'regular expressions', das mächtigste interne Kommando
                     der bish! Seit dem Auftritt der Kommandos  findccc  und
                     findcs  gilt dies allerdings nicht mehr.
                     catv ist als Bestandteil von bish64 64-bit-fähig.
                     ---
                     catv  ist prinzipiell wie  cat  konzeptioniert,
                     jedoch werden als Datenquellen Konstanten und/oder
                     Variablen und/oder Dateinummern(=offene Datei) und als
                     Datenziel Variablen oder Dateinummern akzeptiert!
                     Zusätzlich können zu jeder Quelle und dem Ziel
                     ein Offset und/oder eine MaxBytes-Anzahl angegeben
                     werden!
                     Noch weiter zusätzlich können die Offsets und Objekte
                     mit mehreren Attributen versehen werden, die die
                     Positionierungsausgangsbasis wählen, und anderes!
                     Die Konstanten werden fast genau so wie die Argumente
                     zum echo-Kommando bearbeitet:  %c gibt es nicht,
                     %n ist nur \n und nicht \r\n, aber %j erzeugt \r\n,
                     und %123 können ein bis drei Dezimal-Digits sein.
                     Bei einer Konstanten mit '.' anstatt '/' als Startzeichen
                     werden Prozent-Sequenzen nicht umgewandelt --> raw input.
                     ---
                     catv  schreibt die Inhalte aller Quellen in das
                     Zielobjekt hinein.
                     Dabei kann für jedes Objekt die maximale Anzahl Bytes,
                     die gelesen bzw. geschrieben werden, gesetzt werden.
                     Außerdem können Anfangspositionen gewählt werden,
                     ab denen gelesen bzw. geschrieben werden soll.
                     Das Ende des Objektinhalts wird durch einen Doppelpunkt
                     (:) symbolisiert, der Anfang durch fehlende(!) Zeichen
                     ":+-", und die aktuelle Position durch + oder -, wobei
                     durch - gleichzeitig der Offset negativ gemacht wird.
                     Variablen haben natürlich keine 'aktuelle Position'!
                     ---
                     Ein Punkt (.) bewirkt, daß zum Schluß zur am Anfang
                     festgestellten Dateiposition zurückgestellt wird - der
                     Dateizeiger bewegt sich nämlich aufgrund von Lesen
                     oder Schreiben. In diesem Zusammenhang wird darauf
                     hingewiesen, daß man ein und dieselbe Datei einmal zum
                     Lesen und einmal zum Schreiben öffnen kann, wodurch man
                     zwei voneinander unabhängige Dateizeiger erhält.
                     ---
                     Ein Doppelpunkt (:) am Objekt-Bezeichner führt zu einem
                     Abschneiden des Inhalts des Zielobjektes hinter der
                     letzten Schreibposition - es wird also gekürzt, falls
                     die letzte Position vor dem Objektende liegt.
                     Dies jedoch nicht bei gegebener Punkt-Anweisung!
                     ---
                     Die drei Steuerzeichen dürfen beliebig um die Offset-Zahl
                     bzw. den Objektbezeichner herum gesetzt werden.
                     Bei fehlender Offset-Zahl wird  0  angenommen.
                     Die Steuer- und Startzeichen haben für die Shell keine
                     Spezialbedeutung und dürfen nicht maskiert werden.
                     ---
                     Es können ein bis drei Argumentteile -durch Kommata
                     getrennt- angegeben werden:   offset,max,objekt
                     Bei einem Teil wird dieser als Handle oder Name
                     interpretiert, bei zwei Teilen gilt der erste Teil als
                     Max-Zahl, und bei drei Teilen wird der erste Teil als
                     Offset angesehen.
                     Deshalb muß man nötigenfalls  offset,,objekt  setzen, um
                     einen Offset aber keine Max-Zahl anzugeben.
                     ---
                     Als offset und max können direkt Digits (123..), $name
                     als auch name ohne $ (Inhalt=123..) angegeben werden.
                     ---
                     Ein einziges Argument Komma "," oder ",." oder ",r"
                     veranlaßt die Ausgabe der bei der letzten Aktivität
                     gelesenen Byte-Anzahl:
                     Auf die Standard-Ausgabe oder in $. oder $? .
                     ---
                     catv  liest beliebig angebbare Teile aus Datenquellen
                     und schreibt diese Datenkette in einen beliebigen
                     Abschnitt eines Zielobjektes hinein.
                     Ein Zielobjekt wird natürlich nötigenfalls vergrößert.
                     Auch ein Offset über das Objektende hinaus ist möglich!
                     Bei letzterem wird mit Nullen aufgefüllt, bei Dateien
                     jedoch nur, wenn ab dem Offset mindestens ein Byte
                     geschrieben wird.
                     ---
                     Falls eine Variable das Ziel ist, galt eine Grenze von
                     maximal 32 KByte - dies jedoch nur, wenn diese Variable
                     vergrößert werden mußte.
                     Dieser Punkt wurde geändert: catv kann nun bis zum realen
                     Speicherende ${:name} einer Variablen schreiben (s.u.).
                     Eine 0 wird nur hinter das letzte geschriebene Byte
                     geschrieben, wenn die Syntax 'name:' verwendet wird.
                     Variableninhalte in weiten Grenzen können mit den
                     Kommandos  set  und  local  hergestellt werden.
                     Hinsichtlich der Speichergröße gilt das Limit von 32 KB
                     für eine Vergrößerung nach wie vor.
                     catv  kann nun auch bis zum Ende der Speichergröße lesen.
                     Voraussetzung ist, daß 'max' explizit angegeben wird,
                     der 'offset' nicht negativ ist und 'max>0' ist.
                     Siehe auch oben: 'Shell-Variablen und Speicher'.
                     ---
                     Man kann ein und dieselbe Variable mehrmals als Quelle
                     und gleichzeitig als Ziel angeben!
                     Mit catv können Variablen als binäre Speicherflächen
                     benutzt werden! Bei der normalen Argumentbildung wird
                     nämlich das Null-Zeichen als Argument-Ende verwendet.
                     Spezielle Beispiele:
                     Datei mit 50 Nullen:
                             catv /%0 =49,,1  >datei
                     Variable mit 50 Nullen:
                             catv 0,0 =50,,V
                             catv isnichda =50,,V
                             catv 0,isda =50,,V
                     Variable mit 48 Nullen und \r\n:
                             catv        =48,,V
                     ---
                     Voreingestellt ist:   catv  0 =1
                     Bei mit Geräten verknüpften Handles wird nur ein positiver
                     Offset ab aktueller Position berücksichtigt.
                     Ein i-Attribut wird gelöscht, falls ungleich long-size
                     Bytes in eine Variable geschrieben werden.
                     Exit=FALSE bei Fehlern oder falls kein Byte
                     gelesen werden konnte.
                     (Siehe auch  seek,conv,prints(K))
                     ---
                     set a:.100000
                     echo ${:a} ${#a}
                      100000 100000
                     catv /aa =500,,a
                     echo ${:a} ${#a}
                      100000 100000
                     catv /aa =500,,a:
                     echo ${:a} ${#a}
                      100000 502
                     catv /aa =50000,,a:
                     echo ${:a} ${#a}
                      100000 50002
                     catv /aa =99998,,a:
                     echo ${:a} ${#a}
                      100000 100000
                     catv /aa =99999,,a:
                     echo ${:a} ${#a}
                      100000 100000
                     catv /aa =99997,,a:
                     echo ${:a} ${#a}
                      100000 99999
                     catv /aa =99990,,a
                     echo ${:a} ${#a}
                      100000 100000


      sumv  [-bwllLu#v] [iname] [oname]                  (-Z-)
                     Addiert die Werte aller gelesenen Bytes, Worte, Longs
                     oder LongLongs und schreibt die Summe zur Standard-Ausgabe.
                     Gelesen wird von der Standard-Eingabe (0) oder u1..u9.
                     Voreingestellt ist '-b' für 'Bytes'.
                     Wird ein Variablenname angegeben, gelangt der
                     Summenwert dort hinein (oname).
                     Bei zwei Variablennamen wird aus einer Variablen (iname)
                     gelesen, statt per Filedescriptor.
                     Optionsbuchstabe v selektiert iname bei nur einem
                     angegebenen Variablennamen.
                     Die Optionsbuchstaben ll entsprechen L.


      base  [-bwl ll][u0] [iname] [+bwl ll][u1] [oname]       (-Z-)
              BWL LL                BWL LL
              basis                 basis[#]
                     Dieses Kommando ist sehr mächtig und liest, schreibt,
                     umwandelt Zahlen in vielen Darstellungsarten/Basen.
                     Mit 'bwl ll' werden Bytes, Worte, Longs oder LongLongs
                     gelesen bzw. geschrieben.
                     Mit '(B)WL LL' werden Worte, Longs oder LongLongs
                     gelesen bzw. geschrieben, wobei das höchstwertige
                     Byte stets zuerst berücksichtigt wird - wie bei
                     ascii-ZahlenStrings.
                     Dies ist portabel!
                     Beispielsweise werden auf Intel-Prozessoren
                     bei  'base -l +L'  alle Bytes in ihrer Reihenfolge
                     genau umgedreht, weil Intel-Prozessoren das nieder=
                     wertigste Byte auf der untersten Adresse haben.
                     ---
                     uDigit  kann an die Optionen angehängt werden,
                     um andere Handles als 0 und 1 zu verwenden.
                     (Digit==0...9)
                     Hinter den Optionen kann jeweils ein Variablenname
                     angegeben werden, die dann als Quelle bzw. Ziel
                     benutzt werden.
                     ---
                     Bei Angabe einer 'basis' werden Zahlen-Zeichenketten
                     gelesen bzw. geschrieben.
                     Als Basis sind gültig:  2...36,256
                     Bei Angabe eines '#' hinter der Ausgabebasis
                     wird den Zeichenketten  2#,...36#,256#  kennzeichnend
                     vorangestellt.
                     Bei Angabe einer Quellenbasis von '[-]0' oder '-#'
                     wird erwartet, daß die Eingabe-Zeichenketten jeweils
                     mit  2#,...,36#,256#  gekennzeichnet sind.
                     Standardbasis ist immer '10'.
                     Bei Zeichenketten-Eingabe wird erwartet, daß die Ketten
                     durch $IFS-Zeichen getrennt sind.
                     Voreingestellt ist  'base -b +16'.   (Bytes in Hex)
                     Quelle und Ziel sind Standard-Eingabe und -Ausgabe.
                     Exit ist FALSE bei Fehlern.
                     


      alias [Name[=Wert] ...]
      alias -t [Name ...]
                     Definiert für 'Wert' einen Alias-Namen 'Name'.
                     'Name=Wert' muß ein Einzelargument sein.
                     Ohne Argument werden alle Alias-Definitionen gezeigt.
                     Werden nur Namen angegeben, werden die Definitionen zu
                     diesen Namen gezeigt (ohne Option -t).
                     Option -t legt für die angegebenen Namen den dazugehörigen
                     vollen Pfadnamen automatisch als Alias-Wert an.
                     (Tracked Alias) (siehe set -h)
                     Das alias-Kommando bewirkt einen reinen Textersatz.
                     Shell-Interpretation findet nur bei der Definition
                     eines Alias-Namens statt.
                     Alias-Namen sind in Dateien und Funktionen standardmäßig
                     lokal! - wenn nicht 'global' benutzt wird.
                     Exit-Code ist ungleich null, falls ein angegebener Name
                     kein Alias-Name ist (beim Lesen ohne '=Wert').
                     Beispiele:
                          alias cp=COPY  e='echo Fehler!'  "q=exit $EXVAL"
                          alias ..=exit  l=DIR
                          alias -t vi    ==>    vi=/usr/bin/vi
                     'Name' darf auch andere als die oben für Namen
                     zugelassenen Zeichen enthalten.
                     Und '=' als allererstes Zeichen eines alias-Argumentes
                     wirkt dort noch nicht als Trennzeichen!:
                          alias ==echo
                     definiert folglich '=' als Alias-Namen für echo.
                     Nach einem als Trenner bewerteten  =  werden weitere  =
                     nicht mehr als Trenner interpretiert.

      unalias name ...
                     Entdefiniert zuvor definierte Alias-Namen.

      readonly [name ...]
                     Markiert die angegebenen Namen als 'nur lesbar'.
                     Sie können danach auch nicht per unset gelöscht werden.
                     Auch Aliases und Funktionen können schreibgeschützt
                     werden.
                     Ohne Argument werden alle solchermaßen markierten Namen
                     gezeigt.

      export [Name ...]
                     Die angegebenen Variablen werden in die Umgebung
                     (environment) exportiert (DOS-set-Kommando)
                     und sind danach für alle Subprozesse erreichbar.
                     Siehe Option -a.
                     Ohne Argument werden alle bisher exportierten
                     Variablen gezeigt.
                     Wenn der Inhalt einer exportierten Variablen durch
                     Zuweisung geändert wird, wird das Environment
                     ebenfalls mitgeändert.
                     Falls nicht alle Namen gefunden werden, ist der Exit
                     FALSE.

      unexport [Name ...]   (-Z-)
                     Die angegebenen Variablen werden aus der Umgebung
                     genommen und als normale Shell-Variablen deklariert.
                     Ein Export wird also rückgängig gemacht.
                     Exit wie bei 'export'.

      env            Entspricht dem UNIX-Kommando  env  ohne Argumente.
                     Entspricht dem DOS-Kommando  set  ohne Argumente.
                     Listet alle Environment-Variablen:  NAME=inhalt

      unset [-fse] Name ...   (-Z-)(se)
                     Die angegebenen Variablen werden gelöscht.
                     Das gilt auch für einen ggf. exportierten Inhalt.
                     Option -f lenkt auf Funktionsnamen.
                     Mit den Optionen -s und -e kann die Löschung selektiv
                     nur für Shell- oder exportierte Shell-Variablen erfolgen.
                     Es kann jeweils nur eine der Optionen angegeben werden.
                     Nur wenn alle angegebenen Namen -unter Einbeziehung der
                     Optionen- gefunden werden, ist der Exit=0=TRUE.

      unsetenv  Name ...   (-Z-)
                     Wie Kommando 'unset' (s.o.),
                     jedoch es werden außer exportierten auch Variablen aus
                     dem Environment gelöscht, die nicht von der Shell
                     exportiert wurden, sondern beim Aufruf schon existierten.
                     Nicht exportierte Variablen bleiben unberücksichtigt,
                     ebenso die Syntax-Regeln für Namen.

      local [ Name[=[Wert]] ... ]             (siehe auch set)  (-Z-)
      local [ Name:cn  Name:d.n ... ]         (siehe auch set)  (-Z-)
      local :[[+-]Ziffern] Name ...           (siehe auch set)  (-Z-)
                     Definiert - und setzt optional - lokale Variablen.
                     Nach Shell-Start und für jedes Shell-Script und jede
                     Shell-Funktion, u.ähnl., steht hierfür eine exklusive
                     Speicherfläche zur Verfügung.
                     Die lokalen Namen verdecken gegebenenfalls gleichlautende
                     globale Namen und lokale Namen tieferer Ebenen.
                     Sie sind tatsächlich lokal, und nicht, wie in der
                     UNIX-Korn-Shell, in weiteren, verkettet aufgerufenen
                     Funktionen ebenfalls bekannt.
                     Dateilokale Variablen sind in den Funktionen der
                     jeweiligen Datei bekannt. (s.u.'static')
                     Setzen (name=wert) solcher ist jedoch nicht erlaubt.
                     inh:A70
                          Setzt Variable 'inh' mit 70 'A': "AAAAAAAAAAAAAA..."
                     inh:65.70
                          Setzt Variable 'inh' mit 70 'A': "AAAAAAAAAAAAAA..."
                     Das Kommando  set  macht dies für globale Variablen.
                     ---
                     Durch  : var      wird Länge ${#var} auf ${:var} gesetzt,
                     welche das Maximum ist.
                     Durch  :1234 var  wird Länge ${#var} auf 1234 gesetzt.
                     Durch  :+123 var  wird Länge ${#var} um 123 erhöht.
                     Durch  :-123 var  wird Länge ${#var} um 123 reduziert.
                     Der Inhalt von Variablen wird hierbei nicht verändert.
                     Zu kleine oder zu große Werte werden intern korrigiert.
                     Durch  inh:x70  kann ${#inh} immer wieder auf die alte
                     Länge gesetzt werden, nach beispielsweise  inh=reste;
                     ---
                     Die 'normalen' globalen Variablen sind natürlich auch nur
                     im aktuellen Shell-Prozeß bekannt.
                     Wenn man also 'bish script' anstelle von '. script'
                     aufruft, ist dieser Vorgang isoliert und in dieser
                     Hinsicht unabhängig.
                     Darüber hinaus gültig sind nur Environment-Variablen, die
                     im aktuellen und in allen Kind-Prozessen bekannt sind.
                     ---
                     Vordefinierte Variablen und Funktionsnamen sind stets
                     global, und lokale Namen können nicht exportiert werden.
                     local  ohne Argument setzt ein eventuell gesetztes
                     global-flag zurück (das lokal ist).
                     Auf Namen, die die Shell benutzt, wie PWD, SECONDS, etc.,
                     sollte  local  nicht angewandt werden.

      static [ Name[=[Wert]] ... ]   (-Z-)
                     Definiert statische lokale Variablen, deren Inhalt
                     zwischen Funktions- und Script(. script)-Aufrufen
                     erhalten bleibt. Die Namen sind lokal.
                     Gemäß folgender Reihenfolge wird nach definierten
                     Variablen gesucht (unset,readonly,...):
                          funktions-lokal nicht-statisch
                          datei-lokal     nicht-statisch
                          funktions-lokal statisch
                          datei-lokal     statisch
                          global
                          Environment
                     Das static-Kommando setzt statische Variablen nur,
                     wenn sie noch nicht existieren.
                     Dieses Kommando sollte nicht unnötig verwendet und
                     nicht auf unnötig viele Namen angewandt werden,
                     weil die Inhalte und die verlängerten(!) Namen
                     den globalen Speicher belegen.
                     Namensbildung:
                          script_name@funktions_name@variablen_name
                     Die ersten beiden Namen können fehlen.

      global [+]     Sperrt den Zugriff auf lokale und -statische Namen,
                     bis local ohne Argument aufgerufen wird.   (-Z-)
                     Option + wirkt wie 'local'.
                     Die Sperre gilt nicht für die Kommandos local und static.
                     global ist lokal innerhalb von Funktionen und Scripts.
                     Eine Sperre ist nützlich bei eventueller Namensgleichheit.

      localset       Wie  set  ohne Argumente. Zeigt lokale Inhalte.   (-Z-)

      array  [a [b]] NAME [ arg ... ]   (-Z-)
      array  Name=NAME  index
      NAME$i=wert
                     Die erste Variante dieses Kommando erzeugt ein Array,
                     indem für jedes Element ein Name 'NAMEindex' gebildet
                     und diese Variable dann gesetzt wird.
                     Mit a und b ist ein Zahlenbereich für 'index' wählbar,
                     wobei a auch größer als b sein darf.
                     Standardwerte sind a=1 und b=a+anzahl_args-1.
                     Elementnamen außerhalb a-b werden nicht erzeugt;
                     überzählige args werden dann ignoriert.
                     Überzählige Elementnamen werden leer ("") gesetzt.
                     Wenn nur ein Array-NAME angegeben ist, wird dieses
                     Array gelöscht.
                     Innerhalb von Funktionen werden lokale Arrays erzeugt,
                     falls 'global' nicht gesetzt ist.
                     (s.u. set -A ...)
                     Die zweite Variante liest den Elementinhalt NAMEindex
                     und schreibt ihn in die Variable Name.
                     Als index können eine dezimale Konstante oder ein
                     Variablenname eingesetzt werden, wobei typeset-i-Namen
                     ebenfalls berücksichtigt werden.
                     Wenn NAMEindex undefiniert ist, wird Exit=1 gesetzt.
                     Diese Art des Umgangs mit Arrays hat den Vorteil, daß
                     sämtliche Argumente durch Shell-Interpretation entstanden
                     sein können!
                     Die dritte Variante ist für Einzelzuweisungen und hat
                     mit diesem array-Kommando eigentlich nichts zu tun.

      shift [n]      Die positionalen Parameter werden nach unten geschoben.
                     $n+1 wird zu $n, usw.  Voreinstellung von n ist 1.
                     (siehe $#)

      ifdef [-seEf] Name ...   (-Z-)
                     Antwortet mit einem TRUE-Exit-Code (0), wenn alle
                     angegebenen Variablen-Namen definiert wurden.
                     Andernfalls ist der Exit-Code=1.
                     Gesucht wird nach Shell- und Environment-Variablen.
                     Ohne Argument werden alle undefinierten Variablennamen
                     angezeigt, was sehr viele sein können.
                     Die Optionen -seE sind implizit voreingestellt und
                     bedeuten, daß nach Shell-, dann exportierten Shell-
                     und zuletzt nach Umgebungs-Variablen gesucht wird.
                     Option -f hat Vorrang und zielt auf Shell-Funktionen.

      ifset [-seEf] Name ...   (-Z-)
                     Wie ifdef, jedoch zusätzlich muß jede angegebene
                     Variable mindestens ein Zeichen enthalten.

      ifenv Name ...   (-Z-)
                     Wie ifdef, jedoch wird nur die Umgebung untersucht,
                     ohne die Namen-Syntax zu prüfen.  (s.o. 'env')
                     Entspricht fast 'ifdef -E'.

      conv -eriluLUnSd_D_f_F_h_H_t__T__c_o#O_#a#x#s_  Name ...   (-Z-)
                     Konvertiert den Inhalt der angegebenen Variablen:
                     -l     Zu Kleinbuchstaben (lower case) (-L)
                     -u     Zu Großbuchstaben  (upper case) (-U)
                     -dc    Löscht angegebene Zeichen c.
                     -Dc    Löscht das erste vorkommende Zeichen c.
                     -fc    Löscht angegebene Zeichen c.
                            Jedoch zwischen Gruppen von Zeichen ungleich c
                            wird ein Zeichen c belassen:
                            ///a///b/// ==>  a/b
                     -Fc    Wie -fc, jedoch wird zusätzlich vorne
                            ein Zeichen c belassen:
                            ///a///b/// ==> /a/b ; /// ==> / ; / ==> /
                     -hc    Ersetzt alle Folgen cHH durch den Hex-Wert.
                     -Hc    Wie -hc; ersetzt nur das erste Vorkommnis.
                     -tab   Ersetzt alle Zeichen a durch b.
                     -Tab   Ersetzt das erste vorkommende Zeichen a durch b.
                     -cc    Liefert die Anzahl gefundener c in $. hinein.
                     -a#    Addiert den Wert # (+/-) zu allen Zeichen.
                     -x#    Der Inhalt wird mit dem Wert # per XOR verknüpft.
                     -o#    Angabe eines Offset # (+).
                     -Oc#   Stellt auf den Offset des #-ten Zeichens c.
                            Liefert diesen Offset in $. hinein.
                     -sc    Füllt Zeichen c in die Variable(n).
                            Länge ${#var}-Offs.
                     -S     Der Inhalt wird zeichenweise sortiert: Shakersort+
                            Die Anzahl Vertauschungen wird in $. gespeichert.
                            Diese Anzahl ist für Analysezwecke bestimmt.
                            Eine Zufalls-Zeichenkette[64] hat z.B. 677
                            Vertauschungen zur Folge, in 10 Runden.
                     -r     Der Variableninhalt wird zeichenweise umgedreht.
                     -i     Der Inhalt wird zeichenweise überschrieben
                            mit den Ziffern 0|1 für gerade|ungerade.
                     -n     Der Inhalt wird nach der längsten aus gleichen
                            Zeichen bestehenden Zeichenfolge durchsucht.
                            "hfyweetwegfffehgegl" liefert 3 in $. hinein.
                            Diese Option ist für Analysezwecke bestimmt.
                     -e     Es gilt nun -tba -Tba, Exchange/Austausch.
                            Diese Option toggle-t sich.
                     Wertangaben # werden dezimal vorausgesetzt.
                     Die Optionen müssen als eine Zeichenkette -ooooooo
                     angegeben werden.
                     Readonly- und Environment-Variablen werden nicht
                     verarbeitet!
                     Auf jeden Variableninhalt werden alle Optionen in der
                     angegebenen Reihenfolge angewendet.
                     Jede Option kann beliebig oft angegeben werden.
                     Falls nach einer Option ein oder zwei Zeichen (c,ab)
                     stehen sollen, werden diese unbedingt gelesen, ggf. auch
                     Null-Zeichen!:
                          conv -t b vname
                     Ersetzt alle \0-Bytes in der Variablen vname durch 'b',
                     weil der Argumentspeicher folgendermaßen aussieht:
                          "conv\000-t\000b\000vname\000"
                     Die Optionen  -etb vname  sind hier alternativ (e):
                          "conv\000-etb\000vname\000"
                     Wird ein Zeichen c oder a entdeckt, wird jeweils(!) nach
                     der Gleichheitsprüfung dessen Offset in $. gespeichert.
                     Dies wird durch eine erfolgreiche Option O unterdrückt.
                     Bei den Optionen O und c wird der Exit gesetzt:
                          auf 1, falls das Zeichen nicht gefunden wurde,
                          auf 2, falls es wegen zu großem Offset (o#)
                          gar nicht gefunden werden konnte.
                     Der Offset in $. ist -1 bei Nichtfinden.
                     Bei den Optionen c,n,S wird der Exit auf 1 gesetzt, falls
                     der Zähler==0 ist. Der Exit wird auf 3 gesetzt, falls
                     die Funktionen S,r,n einen zu kurzen Inhalt entdeckten,
                     sodaß sie nicht mit ihrer Arbeit beginnen konnten.
                     Die Ressourcen $. und Exit ($?) sind nur einmal vorhanden,
                     weshalb eine mehr als einmalige Verwendung pro Kommando
                     unlogisch ist und berücksichtigt werden muß.
                     Environment-Variablen werden nicht berücksichtigt.
                     Siehe auch tr(K), set, local.
                     Anstelle von  conv -sc var ...  kann mit den Kommandos
                     set  und  local  die Syntax  var:c${#var}  var:#.${#var}
                     bei bereits bestehenden Variablen verwendet werden.

      cmpv [-i] name1 name2                                        (-Z-)
                     Vergleicht Variableninhalte.
                     Durch Option -i werden {a-z} = {A-Z} und alle weiteren
                     Buchstaben des ISO8859-15 in diesem Sinne gleichgesetzt.
                     Bei Ungleichheit ist der Exit 1 oder 2.
                     Bei ungleicher Variablenlänge ist der Exit 4 oder 8
                     plus gegebenenfalls 1 oder 2.
                     Bei undefinierter Variable ist der Exit=16.
                     $. enthält den Offset derjenigen Zeichenstelle bis zu der
                     geprüft werden konnte, also den der Ungleichstelle
                     oder aber die (kürzere) Inhaltslänge.
                     Der Exit ist nur bei Gleichheit beider Inhalte TRUE (0).
                     Bei -i wird bei Ungleichheit stets 1 zum Exit addiert
                     und $. wird nicht bedient.

      copy1v?  quelle    ziel1  ziel2                              (-Z-)
      copy2v?  quelle1 quelle2  ziel                               (-Z-)
                     Kopieren in Abhängigkeit vom Exit-Code entweder den Inhalt
                     einer Quell-Variable in eines von zwei Zielen, oder aber
                     den Inhalt einer von zwei Quellen in die Zielvariable.
                     Bei vorliegendem Exit=TRUE gilt  ziel1  bzw.  quelle1.
                     Diese Kommandos selbst verändern nicht den Exit-Code.
                     Die Kommandos vergrößern nötigenfalls eine Zielvariable
                     oder legen eine solche neu an.

      xchgv  name1 name2                                           (-Z-)
                     Tauscht die Inhalte beider Variablen gegeneinander aus.
                     Die Variablen müssen groß genug sein für den Inhalt der
                     jeweils anderen Variable:  ${#name} -> ${:name}
                     Das Kommando legt keine temporäre Variable an, sondern
                     tauscht byte-weise aus.
                     Die Inhalte können somit beliebig groß sein, ohne daß ein
                     Variablen-Management erforderlich ist.
                     Das Kommando verändert nicht den Exit-Code.

      eval [Arg ...]
                     Die Shell wertet die Argumente aus und führt das
                     Ergebnis sich selbst als Eingabe (erneut) zu.
                     Beispiel:   A=aaaaa
                                 B='test $A %> AAA && echo $A'
                                 eval $B   schreibt aaaaa auf den Bildschirm.
                     Siehe Kommando 'run?'.

      trap  Kommando-Arg  signal ...
                     Mit dem Kommando trap können unter UNIX den über dreißig
                     vorhandenen Signalen (0...>30) Kommandos zugeordnet
                     werden, die dann bei Eintritt des entsprechenden Signals
                     ausgeführt werden.
                     Unter DOS gibt es nur <Ctrl><C> als verwertbares Signal.
                     Deshalb wurden drei Signalnummern folgendermaßen
                     zugeordnet:
                          0      exit-Kommando
                          1      Bei Fehlermeldung
                          2      Bei <Ctrl><C>
                     Das Kommando-Arg muß ein einzelnes Argument sein.
                     Beispiel:
                          trap '. ~\logout; echo $NKDO:Shell-ENDE' 0
                     Man beachte: bei dieser Maskierung ('') werden $NKDO
                     und ~ erst bei der späteren Ausführung interpretiert.
                     trap-Argumente werden als Funktionen abgespeichert.
                     Achtung!:
                     Trap-'Funktionen' können sich nicht selbst und auch
                     nicht gegenseitig aufrufen.
                     Beispielsweise per trap eine Funktion aufrufen, die
                     das exit-Kommando aufruft und gleichzeitig die
                     exit-Signalnummer 0 angeben. (Indirekte Rekursion!)

                     Achtung! Unter DOS darf man nicht mit einer stets
                     einwandfreien Funktion der <Ctrl><C>-Unterbrechung
                     rechnen. Es ist wohl so, daß man eine laufende
                     nichtinteraktive Shell dadurch abbrechen kann,
                     jedoch die Aktionen, die per  trap '...' 2  ausgeführt
                     werden sollen, werden zumeist nur ausgeführt, wenn die
                     Shell zum Unterbrechungszeitpunkt gerade auf eine Eingabe
                     von der Standard-Eingabe wartet.
                     Wenn man komplexere Aktionen per  trap '...' 2  definiert,
                     muß man mit regelmäßigen Problemen mit gleichzeitigem
                     Dateizugriff (share) rechnen - trotz entsprechender
                     Maßnahmen, und auch, wenn solche Dateizugriffe
                     offensichtlich nicht vorliegen.

      exec [Kdo [Arg ...]]
                     Das durch die Argumente angegebene Kommando wird
                     anstelle der aktuellen Shell ausgeführt.
                     Es gibt keine Rückkehr von einem fehlerfreien
                     exec-Aufruf mit Argument(en).
                     Ohne Argument ist exec ein Null-Kommando ohne Effekt.

      extern Kdo [Arg ...]   (-Z-)
                     Kdo wird als externes Kommando ausgeführt.
                     Hilfreich bei Namensgleichheit.

      system Kdo [Arg ...]   (-Z-)
                     Die Argumente werden an die System-Funktion
                     'system(char *);' übergeben. (DOS: COMSPEC/command.com)
                     Das ist auch -automatisch- der Fall, wenn ein Kommandoname
                     nur aus zwei oder mehr Großbuchstaben A...Z besteht
                     oder mit .bat oder .BAT erweitert ist.
                     Laufwerkbezeichner (X:) gelten hier auch.
                     Man beachte:
                          DIR \verz /s/b/a:d > datei
                     Umlenkung wird von bish durchgeführt.
                          DIR "\verz /s/b/a:d > datei"
                     Umlenkung wird von "system" durchgeführt.
                     Der Exit-Code des angesprochenen Kommando-Interpreters
                     wird übernommen:  Exit=system();

      fork  Arg ...
                     Entsprechend der Anzahl der Argumente werden ein
                     oder mehr Hintergrund-Prozesse gestartet.
                     Bei interaktiver Shell werden die PIDs
                     zur Standardausgabe geschrieben.
                     Der Parameter $! enthält den jeweils letzten PID.
                     Für jedes Argument wird
                          bish -c 'Arg'
                     im Hintergrund gestartet.
                     Das ermöglicht die Verwendbarkeit der bish-Syntax
                     innerhalb von jedem 'Arg'.

      bg-kdo  &      Das abschließende Zeichen '&' startet
                     das externe Kommando 'bg-kdo'
                     als Hintergrund-Prozeß.
                          bg-kdo  &  kdo ; kdo ...
                     ist ebenfalls möglich, da '&' auch wie ';' wirkt.
                     (Siehe set -U)

      wait  [pid ...]
                     Wartet auf die jeweilige Beendigung (exit)
                     der Kind-Prozesse des Aufrufers.
                     Ohne pid-Argumente wird auf alle CHILDs
                     gewartet, mit pid-Argumenten auf die
                     CHILDs mit den angegebenen PIDs.
                     Bei interaktiver Shell werden die PIDs jeweils
                     nach CHILD-exit zur Standardausgabe geschrieben.
                     Der Exit-Kode ($?) wird nach jedem exit eines
                     CHILDs mit dessen Exit-Kode gesetzt.

      kill  [-signo] pid ...
                     Beendet Prozesse, die den angegebenen PID haben.
                     Standard-Signalnummer ist 15 (SIGTERM).
                     [SIGINT==2, SIGKILL==9]
                     Exit wird gesetzt.
                     Bei TRUE-Exit (0) und interaktiver Shell
                     wird der jeweilige PID zur Standardausgabe
                     geschrieben.

      prompt                 (-Z-)
                     Öffnet eine interaktive Shell mit Kommandozeile (und
                     mit Prompt) innerhalb(!) des aktuellen Shell-Prozesses.
                     Dies ist beispielsweise sinnvoll aus einem Skript heraus.
                     Verlassen kann man diese Sitzung mit 'return'.
                     autoexec.bish wird hier nicht abgearbeitet, und das
                     Verzeichnis wird nicht auf das Startverzeichnis zurück=
                     gestellt, sofern gewechselt wurde.

      set [ Name[=[Wert]] ... ]           (siehe local)  (-Z-)
      set [ Name:cn  Name:d.n ... ]       (siehe local)  (-Z-)
      set :[[+-]Ziffern] Name ...         (siehe local)  (-Z-)
      set [{-+}afhnpuvxBCEINOPSUX9! - --] [ -/+A array_name [arg ...] ]
                     - setzt Optionen, + setzt Optionen zurück.
                     Die meisten dieser Optionen können auch beim Aufruf
                     der Shell angegeben werden.
                     echo $-  zeigt die aktuell gesetzten Optionen.

                     Ohne Argumente zeigt set sämtliche definierten
                     Variablen und Shell-Funktionen.
                     Spezial-Variablen, wie RANDOM und SECONDS, werden dabei
                     nicht aktualisiert.

                     Optionen:
                     -A   Erzeugt ein Array, beginnend mit Element 0, in
                          Abhängigkeit von der arg-Anzahl.
                          Das angegebene Array wird zuvor pauschal gelöscht,
                          jedoch nicht bei +A anstelle von -A.
                          Für lokale Arrays siehe oben 'array'.
                     -a   Alle folgenden Variablen werden bei Definition
                          automatisch exportiert.
                     -f   Schaltet Dateinamen-Expansion ab.
                          $] wird bei -f/+f auf 0 gesetzt.
                     -h   Jeder Kommandoname, zu dem erfolgreich ein Pfadname
                          gefunden wurde, wird automatisch als entsprechendes
                          Alias angelegt. Das gilt nicht, wenn der Kommandoname
                          länger als 31 Zeichen ist.
                     -n   Liest Kommandos und überprüft auf Syntaxfehler,
                          führt sie aber nicht aus.
                          Wird von interaktiven Shells ignoriert.
                     -p   Ausführung von $HOME\autoexec.bish wird unterbunden.
                     -u   Zugriff auf undefinierte Variablen ist ein Fehler.
                     -v   Schreibt Eingabezeilen aus wie gelesen.
                     -x   Schreibt Kommandos mit Argumenten bei Ausführung aus.
                          Per dieser Option ausgegebenen Zeilen wird
                          "+ " vorangestellt.
                          Die Standard-Fehlerausgabe wird benutzt.
                          Es werden nur Zuweisungen und klassische Kommandos
                          ausgegeben, nicht jedoch ((...)), while..., etc.
                     -B   Wählt den Backslash (\) als Maskierzeichen,
                          oder das Prozentzeichen (%) per +B .
                          Voreingestellt ist '%'.
                          Der Backslash kann unter DOS sehr stören:
                               echo "C:\\\\DOS\\\\XCOPY.exe : $FLG"
                     -C   Bei einigen Fehlern wird fortgefahren.  (Continue)
                          Funktion nur bei nichtinteraktiver Shell, innerhalb
                          von Dateien und Funktionen und während des Prompt-
                          -Kommandos.
                          Diese Option kann bei unbedachter Verwendung
                          gefährlich werden!
                          Man sollte erst testen und dann gezielt Kommando(s)
                          mit  set -C; ...; set +C  umrahmen.
                          Ein besserer Weg ist, potentielle Fehler vorher
                          festzustellen, um dann individuelle Maßnahmen und
                          Fehlermeldungen vorzunehmen.
                     -E   Aktiviert den Kommandozeilen-Editor.
                     -I   Die Shell kann von der Tastatur normalerweise
                          weise durch Eingabe von ^D oder ^Z beendet werden.
                          Option -I verhindert dies. (ignoreeof)
                     -N   Verhindert (unabsichtliche) Veränderung bestehender
                          Dateiinhalte durch Umlenkung  >Datei .
                     -O   Gestattet, daß das Lesen von $. seinen Index
                          inkrementiert, also auf seinen nächsten Wert stellt.
                          (Siehe insbesondere das expr-Kommando.)
                     -P   Ruft eine permanente interaktive Shell auf, die
                          nicht per 'exit' oder EOF (^D), sondern nur per
                          exit -P  verlassen werden kann. (s.o.: exit)
                     -S   Schaltet den internen ANSI-Treiber ein.
                          Voreinstellung ist EIN.
                          Nur bei Win32 (bish32.exe). Siehe ansi®.
                     -U   Für Pipelines (|) werden pipe()-Calls verwendet.
                          Bis auf das letzte werden alle Kommandos in den
                          Hintergrund gesetzt (bg-Kommandos).
                          Nur das letzte Kommando kann ein bish-Buildin sein.
                               echo aBc | tr B Q | tr Q Y
                          /bin/echo, /usr/bin/tr, tr-Buildin.
                               echo aBc | tr B Q | tr Q Y &
                          /bin/echo, /usr/bin/tr, /usr/bin/tr
                          Es kann natürlich
                               bish -p -c '...; catv Z' | ...
                          verwendet werden, denn bish ist ein externes Kommando.
                          Expandierte Kommandozeilen können meist nur 32K
                          lang sein:
                               echo /usr/*/*/* | wc
                          funktioniert nicht mit echten U-Pipes in der bish.
                          (Siehe bg-kdo &)
                     -X   Die Kommandos 'grep' und 'expr' verwenden hierdurch
                          XRA (eXtra erweiterte Reguläre Ausdrücke).
                          Die Kommandos besitzen eigene Optionen -XB bzw. xb
                          mit Vorrang vor der bish-Option. (Siehe xregexp®)
                     -XRE Siehe xregexp®.
                     -9   CloseOnExec-Flag bei fd>9 statt fd>2.
                     -o sid
                          setsid()
                          close
                            Schließt Handles 1,2,0
                          close#
                            Schließt Handle #  (Auch mehrstellig)
                     -!   Bewirkt ein Ignorieren von SIGTERM.
                     -    Schaltet -v und -x ab und stoppt die Suche nach
                     --   weiteren angegebenen Optionen.
                          Beim Aufruf der Shell können so Dateiargumente
                          angegeben werden, die mit - anfangen.
                     -nvx Diese Optionen wurden nur als Randfunktionen
                          implementiert und weisen manchmal ein vielleicht
                          unerwartetes Verhalten auf.
                     Siehe auch 'conv -sc'.

      typeset  [ -+i[4|8]ISfF{s[obase]|obase} ]  [Name[=wert]]...
                     Dieses Kommando ist in Verbindung mit arithmetischen
                     Ausdrücken besonders interessant.
                     Option -f markiert Gleitkomma-Variablen als binär-float.
                     Option -i markiert Variablen als binär-integer.
                     Sie werden solchermaßen besetzt binär gespeichert
                     und nicht als dezimale ascii-Zeichenkette.
                     Optional kann -i4 oder -i8 angegeben werden, was die
                     Breite in Byte festlegt.
                     Ohne die Breitenangabe wird diejenige Breite verwendet,
                     die durch Option -S oder -I (s.u.) angezeigt wird.
                     In Verbindung damit kann eine Ausgabebasis festgelegt
                     werden, die bei Substitution ($name) und 'set' zum
                     Tragen kommt.
                     Bei Wertzuweisung kann eine (Eingabe-)Basis (base#)
                     angegeben werden, wie weiter oben erklärt, die nur
                     benutzt wird, um die 'obase' zu setzen, wenn 'obase'
                     nicht gegeben oder Null ist.
                     Mit einer Eingabebasis können Variablen NICHT belegt
                     werden, diese dient nur als Wegweiser zum Zeitpunkt
                     der Konstantenumwandlung!
                     ---
                     Der Sinn von if-Attributierung ist der Wegfall von
                     unablässigen Konvertierungen zwischen lesbarer
                     ascii-Zeichenkette und binär.
                     if-Variablen können auch außerhalb von arithmetischen
                     Ausdrücken gesetzt und einander zugewiesen werden;
                     falls eine Darstellung anders als dezimal gewählt wird,
                     muß aber diese Basis explizit angeben werden:
                     Name=base#const
                     Optionen +i oder +f entfernen if-Attribute.
                     Wenn nur obase gegeben ist, wird nur diese neu gesetzt,
                     falls es sich um eine i-Variable handelt.
                     Ohne Namenargumente werden alle if-Variablen gelistet.
                     Namen werden in Dateien und Funktionen standardmäßig
                     lokal angelegt! - wenn nicht 'global' benutzt wird.
                     ---
                     Option -s[obase]  setzt die Basis für die Substitution
                     eines arithmetischen Ausdrucks $((...)).         (-Z-)
                     Dies kann auch ausdruck-lokal vorgenommen werden. (s.o.)
                     Ohne 'obase' wird die aktuelle Basis gezeigt.
                     Die Basis von f-Float ist nicht einstellbar.
                     ---
                     Option -S oder -I zeigt die Länge eines i-Integer
                     in #Byte. Dies gilt nicht für -i4 und -i8. (-Z-)
                     Option -F zeigt die Länge eines f-Float in #Byte. (-Z-)
                     Diese Längen sind wichtig u.a. zum Anlegen binärer Arrays.
                     ${#name} zeigt hier nicht die wirkliche Länge, sondern
                     die Länge als konvertierte Zeichenkette.
                     ---
                     Die Interoperabilität zwischen Objekten mit binärem
                     Inhalt und ungleichem Typ ist weitgehend gegeben.
                     Ändernd können Zuweisungen sein, besonders zwischen
                     Integer und Float.
                     Es können leicht Versuche mit Kontrolle danach
                     vorgenommen werden:
                       typeset
                       a=123.0:f16
                       b=7637.0:f16
                       c=0.0:f16
                       i8=0#567:i8
                       i4=0#89:i4
                     ---
                     Weitere Optionen, die die Original-ksh hat, sind hier
                     unnötig, weil sie von mehreren anderen Kommandos
                     erledigt werden können.

      type                   Name ...
      whence [-pev-] [vname] Name ...
                     Für jeden Namen wird angezeigt, wie er interpretiert
                     würde bei Verwendung als Kommandoname oder Name.
                     Gegebenenfalls wird ein Pfadname gebildet.
                     Nur das erste Argument wird auf Optionen geprüft.
                     Option -- hat nur Isolationswirkung.
                     Option -v verlangt 'vname' als Variablenname, die
                     mit einem Pfadnamen (-p) oder 'Name' gesetzt wird.
                     Option -v setzt den Exit==FALSE bei Mißerfolg.
                     Bei -v und mehreren 'Namen' würde 'vname' immer
                     wieder überschrieben.
                     Option -p schaltet die Nur-Pfadsuche ein.
                     Option -e unterdrückt die Ausgabe und setzt stattdessen
                     den Exit-Code folgendermaßen:               (-Z-)
                        nicht_alle_angegebenen_namen_gefunden    Exit=0
                        Internes Kommando oder Schlüsselwort     Exit=1
                        Alias-Name                               Exit=2
                        Internes Kommando                        Exit=3
                        Shell-Funktion                           Exit=4
                        Shell-Variable                           Exit=5
                        Environment-Variable                     Exit=6
                        Kommando für 'system()'                  Exit=7
                     -p:
                        Batch-Datei                              Exit=8
                        Shell-Script für: 'shell-pfad'           Exit=9
                        Externes Kommando                        Exit=10
                     Bei mehr als einem Namen ist der Exit dem letzten
                     zugeordnet.
                     Achtung! Ein 'Fehler' ist hier ausnahmsweise Exit=0.

      sleep [-m] [n]      (-Z-)
                     Bewirkt einen Stop mit einer Länge von n Sekunden.
                     Voreingestellt ist n=1.
                     Option -m stellt auf n Millisekunden um, wobei die
                     Auflösung in der Regel 10 ms beträgt.
                     Hier gibt es keine Voreinstellung.

      times          Schreibt die bisher aufgelaufene Zeitdauer [sec]
                     seit Start der Shell aus.

      systime [-t] [name|wert]       (-Z-)
                     Setzt oder ermittelt die Systemzeit (Datum+Uhrzeit).
                     Ein angegebener Zahlenwert setzt die Systemzeit.
                     Andernfalls gelangt die Systemzeit in eine Variable,
                     falls ein Name angegeben wurde, oder wird
                     zur Standardausgabe geschrieben.
                     Der Zeitwert ist eine dezimale Zahl, die die Anzahl
                     Sekunden seit 1.1.1970 00:00:00 darstellt:
                          912345678
                     Option -t schaltet ein aufgeschlüsseltes Wertformat ein:
                          [CC]YYMMDDhhmm[.ss]
                     Linear vom Jahrhundert bis zum Sekundenwert.
                     Dieses Format wird neuerdings von vielen Kommandos
                     einheitlich beherrscht.
                     Option -t ist entbehrlich, falls der Punkt (.)
                     im Wert enthalten ist.
                     Mindestens Jahrhundert und Sekunden sind optional.
                     Bei diesem Kommando reicht sogar ".", wodurch die
                     Sekunden zu 00 und die anderen Werte aus der
                     aktuellen Zeit ergänzt werden.
                     Siehe auch:  tz  ctime  fstat

      tz  [{[-]stunden|sekunden}|set]      (-Z-)
                     Setzt einen Zeitzonenwert (timezone),
                     die Differenz zwischen GMT-Zeit (GreenwichMeanTime)
                     und lokaler Zeit.
                     Für MEZ(CET)-Zeit beträgt dieser Wert
                     -1 Stunde bzw. -3600 Sekunden.
                     Ein angegebener Wert, der nicht ohne Rest durch
                     60 teilbar ist, wird als Stundenwert aufgefaßt,
                     andernfalls als Sekundenwert interpretiert.
                     --
                     Option 'set' ruft tzset() [$TZ] auf
                     und setzt dann in Abhängigkeit von 'daylight'
                     entweder mit 'alttime' oder mit 'timezone'.
                     --
                     Ohne Argument wird die aktuelle Einstellung
                     -stets in Sekunden- zur Standardausgabe geschrieben.
                     Voreingestellt ist 0.
                     Dieses Kommando beeinflußt die Kommandos
                     systime und fstat (a-,m-,ctime), und
                     ist unter Unix immer von Bedeutung.
                     Während der Sommerzeit kann man -2 setzen.


      ctime  [-t] name... wert... | wert... name...                (-Z-)
                     Konvertiert die beiden Zeitwertformate, die bei den
                     Kommandos  fstat und systime  verwendet werden.
                     Dieses Kommando bemerkt fast vollautomatisch
                     anhand der Argumentart und -häufigkeit, was wie
                     umgewandelt werden soll.
                     Alles außer 88888888 --> 88888888 ist möglich.
                     Ohne Namenangabe wird zur Standardausgabe
                     geschrieben.
                     Ein Name '-' gilt zwar als solcher, jedoch wird zum
                     Schluß keine Variablenzuweisung vorgenommen.
                     Dies ist ein Auslassungsname, der nur positioniert.
                     Ganz ohne 'echten' Namen wird immer zur StdAusgabe
                     geschrieben.
                     Mehr als ein Name erzeugt stets das -t-Format.
                     Sonderfall:  Bei Angabe von .ss und trotzdem
                                  Option -t ist das Ausgabeformat ebenfalls
                                  vom -t-Typ  -  auch bei nur einem(!) Namen.
                     Beispiele:
                          ctime  888888888
                          ctime  name 888888888
                          ctime  888888888 name
                          ctime  name - name 888888888
                          ctime  name [CC]YYMMDDhhmm[.ss]
                          ctime  name [CC] YY MM DD hh mm [.ss]
                          ctime  name [CC]YY MM DD hh mm [.ss]
                          ctime  -t name [CC]YYMMDDhhmm
                          ctime  -t YYMMDDhhmm.ss
                          ctime  -t - - YYMMDDhhmm.ss
                          ctime  ...
                     Das Beste ist, man probiert das in der Kommandozeile
                     mit aktiviertem Kommandozeilen-Editor mal aus.
                     Dieses Kommando wandelt NUR um,
                     es werden keinerlei Zeiten GESETZT.


      fstat [-|+FitfplugJNsamcbnhTv] [name...|wert...] file...|handle...   (-Z-)
                     Dieses Kommando liefert sämtliche Daten, die im
                     Dateisystem für eine Datei vorhanden sind.
                     Alle Daten, die in diesem Zusammenhang überhaupt
                     gesetzt werden können, kann dies Kommando auch setzen.
                     ---
                     Die Optionen werden nachfolgend mehrmals erklärt:
                     -F     Dateisystem-Nummer (Gerät/device)
                     -i     Inode-Nummer       (DOS-)
                     -t     Datei-Typ          (Dual-Zahl)
                     -f     Datei-Flags        (Dual-Zahl)
                     -p     Zugriffs-Erlaubnis (permission/mode) (Oktal-Zahl)
                     -l     Anzahl Links       (link count)
                     -u     Besitzer-ID        (user-id/uid) (DOS-)
                     -g     Gruppen -ID        (grp -id/gid) (DOS-)
                     -J     Major-Nummer       (Gerät/device)
                     -N     Minor-Nummer       (Gerät/device)
                     -s     Datei-Größe        (size: 32/64Bit)
                     -a     Zugriffs-Zeit      (access) (DOS-)
                     -m     Änderungs-Zeit     (modification)
                     -c     Status-Änderung    (creation) (DOS-)
                     -b     Kreations-Zeit     (inode-creation) (DOS-)
                     -n     Datei-Name
                     -h     Zeigt an, daß Nummern (handle/file_descriptor)
                            geöffneter Dateien angegeben werden, anstelle
                            von Dateinamen.
                            Beim Setzen (+) können Nummern größer als 9
                            nicht verwendet werden.
                     -T     Aufgeschlüsseltes Zeitformat eingeschaltet:
                            CCYYMMDDhhmm.ss  statt  912345678  (s. systime)
                            Von links her weggelassene Angaben werden aus
                            der bisherigen Dateizeit ergänzt.
                     -v     Variablen sollen gesetzt werden, anstelle
                            eines Schreibens zur Standardausgabe.
                            Die Anzahl muß mit den Optionen korrespondieren.
                     Die Optionen müssen als ein einzelnes Argument
                     angegeben werden.
                     Die Optionen -h,-T,-v dienen der Steuerung dieses
                     Kommandos, die anderen bezeichnen Dateiparameter.
                     Ein vorangestelltes Pluszeichen (+) anstelle des
                     üblichen Minus (-) zeigt an, daß Dateiparameter
                     gesetzt werden sollen.
                     Gesetzt werden können:  +fpsam
                     wobei zwischen +a und +m kein Unterschied besteht.
                     Es kann tatsächlich die Dateigröße (+s) gesetzt werden;
                     logischerweise verliert man bei Verkleinerung Daten.
                     Achtung:
                     Die Reihenfolge der Dateiparameter-Optionen wird bei
                     der Ausgabe und beim Setzen von Variablen berücksichtigt!
                     ---
                     Falls keine Parameter-Option -F...-n gegeben wurde,
                     werden automatisch die folgenden gesetzt:  -tfpsmn
                     DOS:
                     Fit    f     p lugJN s          amc        n hTv
                       typ  flags mode    size       time       name
                       1111 111   777     0000000000 9999999999 nnnnnnnn
                       file arch
                        dir  hidden
                         cdev system
                          label
                     UNIX:
                     Fit    f     p lugJN s          amc        n hTv
                       typ  flags mode    size       time       name
                       1111 111   777     0000000000 9999999999 nnnnnnnn
                       file suid
                        dir  sgid/lock
                         cdev sticky
                          fifo
                        bdev
                         bdev
                      (symlink)
                        (symlink)
                     Symbolische Links: siehe test-Kommando
                     Dieses Kommando ist nicht dafür da, um schöne, formatierte
                     Listen zu erzeugen, sondern um Daten komfortabel
                     verarbeiten zu können - ähnlich wie das list-Kommando.
                     ---
                     Falls Dual-/Oktal-Zahlen in Variablen gespeichert
                     werden, kann man nur quasi-direkt damit Berechnungen
                     vornehmen:
                          let "typ=2#$typ, flags=2#$flags, mode=8#$mode"
                     Hier wurde umgeformt; erst hiernach kann man
                     in allen Syntaxformen rechnen:
                          (( typ2=typ&2#11, mode&=~8#200 ))
                          (( typ2=typ&3   , mode&=~128   ))
                          (( typ2=typ&10#3, mode&=~10#128))
                     Der Arithmetik/Logik-Modul erwartet nämlich
                     dezimale Zeichenketten in den Variablen.
                     Auch Compiler können verschiedene Zahlenbasen nur
                     an Konstanten erkennen (789 0567 0xfc8a).
                     ---
                     Beispiele:
                          fstat                      (zeigt Aufrufzeile)
                          fstat     aaa abc ccc *.txt
                          fstat -T  aaa abc ccc *.txt
                          fstat -psmnT  nul aux prn con
                          fstat -Th 0 1 2 10 11
                          fstat -smTv agröße azeit  a
                          fstat -msTv azeit agröße  a
                          fstat +mT  $azeit  bbb ccc
                          fstat -mT          bbb ccc
                          fstat +p  400  bbb ccc          (DOS-Schreibschutz)
                          fstat +fp  111 400  bbb ccc     (DOS-attrib AHSR)
                     Am besten probiert man das mal in der Kommandozeile
                     aus, bei aktiviertem KdoZeilen-Editor (bish -E/set -E).
                     Warnung:
                          Aufpassen bei  +s  !
                     Unter DOS kann der Zeitstempel von Verzeichnissen
                     nicht geändert werden.
                     Indirekt geht das, indem man mittels systime die
                     Systemzeit vorübergehend ändert und währenddessen
                     ein Verzeichnis erzeugt.
                     ---
                     Exit==FALSE falls Dateien nicht geöffnet werden konnten
                     beim Lesebetrieb.
                     Alle anderen Fehler werden 'laut' quittiert.
                     (siehe tz-Kommando)


      fsize  datei ...   (-Z-)
                     Dieses Kommando ist ein Auslaufmodell ! ! !
                     Entspricht:  fstat -s datei...
      fmode  datei ...   (-Z-)
                     Dieses Kommando ist ein Auslaufmodell ! ! !
                     Entspricht:  fstat -p datei...
      mtime  datei ...   (-Z-)
                     Dieses Kommando ist ein Auslaufmodell ! ! !
                     Entspricht:  fstat -m datei...
      stime  time  datei ...   (-Z-)
                     Dieses Kommando ist ein Auslaufmodell ! ! !
                     Entspricht:  fstat +m time datei...


      mktemp  [name [dir]]     (-Z-)
                     Erzeugt eine temporäre Datei.
                     Die Datei hat danach die Größe 0.
                     Eine angegebene Variable wird mit dem Namen
                     dieser Datei gesetzt, andernfalls wird der
                     Dateiname zur Standardausgabe geschrieben.
                     Ohne Angabe eines Verzeichnisses wird das
                     TEMP-/BISHTEMP-Verzeichnis verwendet.
                     Der generierte Pfadname, mit dem die Datei erzeugt
                     wird, ist garantiert konfliktfrei.
                     Die Datei wird nach Erzeugung sofort wieder
                     geschlossen.


      dirname  Pfadname   (-Z-)
                     Die letzte Pfadnamenkomponente wird entfernt und
                     der verbleibende Vorderteil wird zur Standard-Ausgabe
                     geschrieben.
                     Der Basisname wird auch entfernt, wenn dieser ein
                     Directory repräsentiert.
                     Exit-Code ist 1, wenn Pfadname leer oder nicht
                     angegeben ist.

      basename  Pfadname   (-Z-)
                     Die letzte Pfadnamenkomponente wird selektiert und
                     zur Standard-Ausgabe geschrieben.
                     Exit-Code ist 1, wenn Pfadname leer oder nicht
                     angegeben ist.

      fullname [-v-] [vname] Name ...     (-Z-)
                     Jeder 'Name' wird nötigenfalls mit dem Namen des
                     aktuellen Verzeichnisses ergänzt, so daß stets ein
                     voller Pfadname entsteht.
                     Der erzeugte Pfad wird zur Standardausgabe geschrieben,
                     falls Option -v nicht angegeben wurde.
                     Nur das erste Argument wird auf Optionen geprüft.
                     Option -- hat nur Isolationswirkung.
                     Option -v verlangt 'vname' als Variablenname, die
                     mit dem vollen Pfad gesetzt wird.
                     Bei -v machen mehrere 'Namen' keinen rechten Sinn,
                     da 'vname' immer wieder überschrieben würde.
                     Dies ist ein reines Zeichenketten-Kommando, das
                     den erzeugten Namen nicht auf Existenz prüft!

      umask  [ddd]   Setzt oder zeigt die Bit-Löschmaske für die
                     Dateierzeugungsmechanismen.
                     Gesetzt wird bei Angabe einer Zahl in Oktalnotation.
                     Die Bits, die hier angegeben werden, löschen
                     gegebenenfalls im Ursprungsmodus gesetzte Bits.
                     Der (interne) Ursprungsmodus der bish ist 666 / 600(DOS),
                     und 777 / - beim Kommando mkdirs.
                     umask ist voreingestellt:  077 / 177(DOS)
                     wodurch '600' resultiert für Dateierzeugungen
                     und '700' für Verzeichniserzeugungen.
                     Aus '377' resultierte '400' für schreibgeschützte
                     Dateien.
                     Bedeutung:   rwx    rwx    rwx       = 9 Bits
                                  Eigner Gruppe Alle
                     Unter DOS sind nur die beiden linken rw-Bits bedeutsam;
                     es gibt nur die Modi '600' und '400'.
                     Unter DOS wird Schreibschutz (0400) bei Dateierzeugung
                     durch dieses Kommando ignoriert:  siehe fstat

      sane  [q]      Stellt die ursprünglichen Verknüpfungen der   (-Z-)
                     Datei-Handles wieder her, wobei Handles auch
                     geschlossen werden.
                     sane sollte nur auf Grundebene der Shell aufgerufen
                     werden, also beispielsweise nicht innerhalb einer
                     Pipeline.
                     Option q schaltet die Informationsausgabe ab.

      ver [oswntil]  Zeigt die Version des Shell-Programms bish.    (-Z-)
                     o     System
                     s     System
                     w     Ware
                     n     Versionsnummer (hat Vorrang)
                     t     Zeit der Kompilierung
                     i     Informationen
                     l     Limits

      autor          Zeigt genaue Anschrift des bish-Autors.        (-Z-)


      hash           Reservierter Kommandoname.
      mkpath         Reservierter Kommandoname.
      reset          Reservierter Kommandoname.
      function       Reserviertes Schlüsselwort.



    Prompt
      Eine interaktive Shell gibt vor jeder Eingabe einen Prompt-String aus.
      Siehe oben:  Shell-Variablen PS1, PS2.
      Das sekundäre Prompt wird ausgegeben, wenn man <Enter> betätigt hat,
      ein Kommando jedoch noch nicht vollständig ist.
      Besonders häufig kommt es vor, daß man Zeilenvorschübe als Bestandteil
      eines Kommando-Argumentes eingeben will:
           #  ABC="aaaaaa
           >  bbbbbb
           >  cccccc
           >  "
           #  _
      Oder lange Eingaben:
           #  kommando arg arg arg arg > datei  &&
           >  kommando arg arg
           #  _
           #  echo aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa%
           >  aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa > datei
           #  _
      Schleifen, if-elif-else-fi und case-esac  sind bei solcher Zeilen=
      verteilung problematisch, da dies nicht implementiert ist.
      Im Kommandozeilen-Editor ist diese Eingabeart jedoch unsinnig.
      Standardwerte für PS1 und PS2 sind "#  " und ">  ".
      Der Inhalt wird interpretiert und ggf. expandiert.
      Nur die Zeichen  $  %  und  !  haben Spezialbedeutung,
      wobei für  !  eine fortlaufende Kommandonummer eingesetzt wird.
      Beispiel:   PS1='!:$PWD: '
      ---
      Neuere Versionen der bish können in den Variablen PS1 und PS2
      die komplette Syntax benutzen! Die Inhalte werden quasi wie eine
      Shell-Funktion gelesen. Die Länge für die Prompts ist allerdings
      begrenzt, und zwar auf <512 Bytes und 55 Kommando-Argumente.
      Anstelle von '!' muß man hier '$:' angeben.
      Die Voreinstellungen sind:  PS1=' print -nu2 "$:#  "'
                                  PS2=' print -nu2 "$:>  "'
      Das set-Kommando zeigt u.a. diese Inhalte.
      In 'autoexec.bish' bzw. '.bishrc' können abweichende Einstellungen
      vorgenommen werden, z.B.:
      PS1='print -nu2 "%e[s%r%e[53C%e[40;36m"; prints su2-26- $PWD
           print -nu2 "%e[u%e[40;37m$:%e[1m#%e[0m  "'
      Oder man definiert eine Funktion, und dann:  PS1=fname
      (Siehe auch Kommando 'prompt'.)



    Eingabe von der Tastatur
      Die Shell liest von der Standard-Eingabe und überschreibt keine
      eventuellen Tastenprogrammierungen.
      Das Verhalten ist genau so, wie in der Kommandozeile außerhalb der bish!
      Das gilt sehr weitgehend auch bei aktiviertem Kommandozeilen-Editor.


    Aufruf der bish
      Ohne Argument ist bish interaktiv.
      Nach Aufruf wird $HOME\autoexec.bish ausgeführt. Falls HOME undefiniert
      ist, wird \autoexec.bish probiert. (s. Option -p)
      Die Ausführung von autoexec.bish entspricht dem Punkt-Kommando
      '. autoexec.bish'.  Darin vorgenommene Definitionen bleiben also erhalten.
      Wenn Argumente vorhanden sind, die keine Optionen (-o) sind, werden
      diese als Shell-Script mit zugehörigen Argumenten aufgefaßt und
      ausgeführt; die Shell ist dann nicht interaktiv.
      Das gilt nicht, wenn eine der Optionen -isct gegeben ist. In diesen
      Fällen werden die Argumente zu positionalen Parametern.
      Das Shell-Script wird gemäß $PATH gesucht, und nach Abarbeitung von
      'autoexec.bish' wird geprüft, ob darin PATH geändert wurde. Falls ja,
      wird nochmals der Pfad gesucht.

           -c String      Den Inhalt von String liest die Shell als Eingabe.
                          Für String gilt ein Längenlimit von 2 KB.
                            Es gibt hier eine Trennzeichen-Problematik
                            bezüglich "string" und sehr eigentümlichen
                            Verhaltens der in DOS-Entwicklungsumgebungen
                            anzutreffenden Library-Funktionen. (siehe bish(I))
                            (Nur, wenn man innerhalb bish bish -c ... aufruft.)
           -s             Mit dieser Option oder ohne Rest-Argumente liest
                          die Shell von der Standard-Eingabe.
                          Rest-Argumente bilden positionale Parameter.
                          Shell-Ausgabe erfolgt auf die Standard-Fehler=
                          ausgabe.
           -i             Die Shell ist interaktiv per dieser Option
                          oder wenn Shell-Ein- und -Ausgabe mit einem
                          Terminal verknüpft sind.
           -t             Exit nach Ausführung eines einzelnen Kommandos.
                          Sinnvoll bei Aufruf innerhalb eines C-Programms.

      Weitere Optionen:  siehe set-Kommando.


    Signale/Interrupt(Ctrl-C)/Fehlerbehandlung
      bish  fängt Signale ab.
      Eine nichtinteraktive Shell wird in diesen Fällen beendet.
      Eine interaktive Shell wird in Grundstellung gebracht und es wird
      ein Prompt ausgegeben.
      Gleiches gilt bei Fehlermeldungen.
      bish hat annähernd 100 Fehlermeldungen;
      die zugehörige Datei-Zeilennummer [n] wird ggf. ausgegeben.
      Bei Fehlern innerhalb von Funktionen wird der Funktionsname()
      und die betreffende Zeilennummer des Funktionskörpers ausgegeben.
      (auch bei trap- und eval-Expansionen.)
      Die Zeilennummer kann mitunter um 1 zu hoch sein, weil manche Fehler
      erst nach einer abgeschlossenen Zeile erkannt werden.

      Mittels 'set -C; ...; set +C;' (siehe oben) kann man einige Fehler
      auf eine Fehlermeldung reduzieren. Dies ist für Fälle gedacht,
      bei denen man einen nachfolgenden Shell-Exit nicht haben will.
      Allerdings kann ignorieren von Fehlern durchaus im weiteren Verlauf
      einer Abarbeitung großen Schaden anrichten! Denn in der Regel soll ein
      Kommando -das dann beispielsweise nicht gefunden werden kann- Arbeiten
      verrichten, die nachfolgend von Bedeutung sind!



 KOMMANDOZEILEN-EDITOR
      Wird durch  set -E bzw. set +E  ein- bzw. ausgeschaltet.
      Zur Verwendung muß die Shell natürlich interaktiv sein. Außerdem
      muß ein ANSI-Treiber für Escape-Sequenzen geladen sein!

      Editier-Tasten:
           <Esc>          Eingabezeile löschen.
           <Backspace>    Cursor nach links und Zeichen ab Cursor löschen.
           <Delete>       Zeichen löschen. Plus <Backspace>-Funktion.
           <BackTab>      Zeichen löschen.
           <Left>         Cursor nach links.
           <Right>        Cursor nach rechts.
           <Home>         Cursor zum Zeilenanfang.
           <End>          Cursor zum Zeilenende.
           <Insert>       Wechselt vom Überschreib- zum Einfügemodus,
                          und umgekehrt.
                          Der Überschreibmodus wird durch ein helleres
                          aktuelles Zeichen angezeigt.
           <Ctrl+V>       Nach Betätigung gilt ein Steuerzeichen als normales
                          Textzeichen. Ebenso können Zeichen per Dezimalwert
                          eingegeben werden. (s.u.)
                          <Insert> hier wechselt die optische Anzeige des
                          Überschreibmodus zum Einfügemodus - und zurück.

      History-Tasten:
           <Up>           Holt ehemalige Eingabezeile(n) zurück.
           <Down>         Geht wieder in Richtung aktuelle Zeile.
           <PgUp>         Wie <Up>, jedoch mehrere Zeilen auf einmal.
           <PgDown>       Wie <Down>, jedoch mehrere Zeilen auf einmal.
           <Enter>        Aktuelle Zeile wird abgespeichert und der Shell
                          als Input übergeben.
                          Cursor-Position ist bei <Enter> unerheblich.
      History-Funktionen:
           ,x...          Es wird in der Liste der ehemaligen Eingabezeilen
                          nach einer Zeile gesucht, die mit x... beginnt.
                          Gesucht wird in Richtung der ältesten Zeile.
           ?x...          Es wird eine Zeile gesucht, die irgendwo
                          x... enthält.
                          Es werden hier die Ersatzzeichen (?*[) wie bei der
                          Dateinamen-Expansion verarbeitet.
           Diese Zeichen (,?) haben nur als erstes Zeichen Spezialbedeutung.
           Voranstellung eines Trennzeichens hebt die Spezialbedeutung auf.
           Ebenso, wenn sie ganz allein stehen.

      Steuer-Tasten:
           <Ctrl+C>       Interrupt.
           <Ctrl+Z>
           <Ctrl+D>       Beendet die Shell, wenn nicht Option -I gesetzt ist.


      Wenn bei Aufnahmeabsicht einer neuen Zeile in der History-Liste eine
      identische Zeile entdeckt wird, rückt diese Zeile an die aktuelle
      Position. Die neue Zeile wird dann gar nicht erst aufgenommen.

      Die Cursor-Position bei horizontaler Bewegung wird abgespeichert
      und bei vertikaler Bewegung wird Bezug darauf genommen.
      Durch <End> wird diese Bezugnahme (temporär) unterbunden.

      Es können die Zeichen ^A bis ^Z (1-26) eingegeben werden.
      Für Esc, ^C, ^D und andere Steuerzeichen muß zuvor ^V gedrückt werden.
      Sie werden teilweise durch  @  dargestellt.
      Ein TAB wird per  ^  gekennzeichnet.
      Ebenfalls können nach ^V ein bis drei Digits eingegeben werden, um
      Zeichen mittels ihrem Dezimalwert zu schreiben.
      Diese Sequenz wird beendet mit Eingabe des dritten Digits oder sobald
      ein Nicht-Digit auftritt.

      Die History-Liste faßt maximal 128 Zeilen, wobei alle darüber hinaus
      die jeweils älteste überschreiben. (Ringspeicher)
      Eine Zeile kann maximal 126 Zeichen lang sein. Wenn allerdings über
      den rechten Bildschirmrand hinaus geschrieben wird, ist die
      Editierbarkeit eingeschränkt.

      Die Eingabezeilen werden in der Datei  $HOME\history.bish  abgespeichert.
      Der Dateiinhalt bleibt erhalten und wächst von Sitzung zu Sitzung.
      Eine Sitzung wird nur explizit per 'set +E' oder Beenden der Shell
      gelöscht, jedoch nicht durch Unterbrechungen (Fehler,Ctrl+C).

      Während der Eingabe in der Kommandozeile des Zeilen-Editors
      wird ein Abbruch per <Ctrl+C> nicht vom System generiert,
      sondern vom Editor selbst.
      Dies deshalb, weil der Editor nicht von der Standard-Eingabe liest.
      Der Original-Break funktioniert hier nicht.



 HINWEISE
      Diese Manual-Datei ist in der Regel die aktuellste aller
      Manuals zur bish.
      Für die meisten gilt: Copyright © 1995-1997
      Vieles -z.B. Limits- bezieht sich auf die DOS16-Version,
      gilt aber nicht für unix-bish, bish32 oder bish64.
      Auch manche Beispiel-Scripts nehmen nicht Bezug zu neueren
      Leistungsmerkmalen der bish.

      Es erfolgt eine automatische Pfadnamen-Korrektur bezüglich der
      trennenden Schrägstriche '/' <---> '\'.
      Man kann also auch mit der DOS-Version z.B.  /aaa/bbb/ccc
      angeben.
      Dies ist jedoch beim Aufruf externer Kommandos, bei Verwendung
      von 'system' und 'extern' und bei impliziter Verwendung von
      'system' (z.B. DIR ...), alle Argumente betreffend, nicht möglich!
      Unter Unix ist diese Umwandlung nicht aktiv, da dort sämtliche
      Zeichen außer '\0', also 1...255, in Pfadnamen vorkommen dürfen.

      Jedes aufrufende Programm -beispielsweise command.com, das die bish
      aufruft- hat eine Umgebung (Environment), die aus Variablennamen
      und deren Inhalten besteht.
      Diese Variablen sind im aufgerufenen Programm zugänglich, da die
      Adressen dorthinein kopiert wurden.
      Man kann dies als Prozeßkommunikation bezeichnen, die jedoch nur
      in einer Richtung funktioniert, da das aufgerufene Programm dem
      Aufrufer nichts mitteilen kann, sondern nur seinen Kind-Prozessen.
      Die bish hat einen eigenen Speicher für Shell-Variablen.
      Hierhinein kann man Inhalte speichern, die von der Umgebung
      isoliert sind (global,lokal,lokal-statisch,...).
      Man kann aber globale Variablen exportieren, die dann aufgerufenen
      Programmen wiederum als Umgebung bekannt werden.
      Den Speicherplatz stellt der Exporteur zur Verfügung. Die Adressen
      darauf werden in das nächste Programm kopiert.
      Man kann auch Umgebungsvariablen verändern oder löschen.
      Das wirkt aber niemals rückwärts zum Aufrufer! Man hat nämlich nur
      Adressen bekommen, die ggf. von Adressen aus dem eigenen Speicher
      überdeckt werden können.
      Man muß also unterscheiden zwischen reinen Umgebungs-Variablen,
      aus denen nur gelesen wurde, Shell-Variablen, und exportierten
      Shell-Variablen! Die vorletzten können weiter unterteilt werden!

      Die temporären Dateien der bish werden hinsichtlich ihrer Handles
      auf Werte größer 9 justiert, so daß es garantiert keine unerwarteten
      Konflikte mit programmierten Umlenkungen geben kann.



 WARNUNGEN
      Die Shell unterscheidet grundsätzlich Groß- und Kleinschreibung!
      Notwendige Umwandlungen werden automatisch vorgenommen.
      Laufwerkangaben müssen vom nachfolgenden Namen mittels \
      getrennt werden:  c:\name...

      Lokal-statische Namen werden folgendermaßen gebildet:
           script_name@funktions_name@variablen_name
      Man kann erkennen, daß es hier eine Eindeutigkeits-Lücke gibt, wenn
      auch die Wahrscheinlichkeit für einen Fehlzugriff sehr gering ist.
      Wenn ein und dasselbe Script einmal mit dem einfachen Namen und ein
      anderes Mal mit dem vollen Pfadnamen aufgerufen wird, werden jeweils
      unterschiedliche Namen zusammengesetzt!
      Andererseits kann man genau das absichtlich ausnutzen!
      Oder wenn man das Directory wechselt und dort gleiche Namen vorkommen,
      kann unbeabsichtigter Bezug stattfinden. Das läßt sich durch Angabe
      von vollen Pfadnamen vermeiden;  der Vorderteil eines Pfadnamens
      wird abgeschnitten, falls der Pfadname länger als die Hälfte der
      maximalen Pfadnamenlänge (DOS:64-128; UNIX:>=1024) ist.

      Umlenkungen, die ein Vorauslesen erfordern, über die Argumente eines
      'normalen' Kommandos hinaus, kann die bish nicht.
      Schleifen (...done | ...), Blöcke ({...} | ...), Subshells (...),
      können nicht in eine Pipeline hinein schreiben!
      Auch andere Umlenkungen direkt hinter solchen Konstrukten sind nicht
      möglich - eine flexiblere Alternative sind globale Umlenkungen.
      Hinter:
           done  fi  esac
      dürfen TAB und/oder Leerzeichen stehen.
      Es muß ein Zeilenvorschub, Semikolon (;), Kommentar (#) oder EOF folgen.



 LIMITS
      Siehe Kommando ver l
      Die folgenden Limits gelten nur fuer DOS-Versionen.

      31       Zeichen für Namen von Variablen und Funktionen.
      1020     Argumente -insgesamt- im internen Bereich.
      4 KByte  -insgesamt- für die Argumentwerte im internen Bereich.
      127 Byte für die Argumentwerte zu externen Kommandos (DOS).
      128      Globale Namen  (Variablen, Funktionen, Aliases, static-Namen).
      64       Funktionsdefinitionen.
      5 KByte  für globale Inhalte und -namen.
      16       Lokale Namen  pro lokaler Ebene.   (-Z-)
      2 KByte  -insgesamt- für lokale Variableninhalte und -namen.   (-Z-)
      12...18  -fache Verschachtelung bei Funktionen (auch trap,eval).
      30...70  -fache Verschachtelung bei Syntax-Konstruktionen.
      127      Zeichen für Pfadnamen.
      12       Ein-/Ausgabe-Umlenkungen gleichzeitig-verschachtelt.
      15       Unäre Operatoren vor einem Wert  (Arithmetik).
      22       ODER-| beim case-Kommando: pattern[|pattern]...) .
      8        Sprungmarken pro lokaler Ebene.   (-Z-)
      7        Länge goto-Label-Name.   (-Z-)
      2 GByte  bish-Scripts dürfen praktisch beliebig groß sein.
               Das gilt auch für Funktionskörper, Schleifenkörper, etc.,
               für arithmetische Ausdrücke der Formen  ((...)) und $((...)),
               und überall für 'Liste'.



 EXIT-CODE
      Derjenige des letzten ausgeführten Kommandos.
      Bei Fehlern größer 0.


 DATEIEN
      [$HOME]\autoexec.bish   Shell-Script, wird nach Aufruf ausgeführt.
      $BISHTEMP\...           Temporäre Dateien.
      [$HOME]\history.bish    History-Liste des Kommandozeilen-Editors.


 SIEHE AUCH
      bish(A...Z), echo(K), test(K), cat(K), tr(K), wc(K), cut(K),
      regexp®, expr(K), grep(K), tee(K), crc(K), line(K), rel(K),
      bgrep(K), calc(K), timex(K), dd(K), hx(K), cmp(K), comx(K),
      touch(K), dat(K), readc(K), l(K), pg(K), man(K), ansi®.


 VERSION
      bish(.exe), Version 7.33

 AUTOR
      bish  wurde entwickelt von:
      Helmut Schellong, Vlotho
      Copyright © 1995-2022





^

 cat(K)                                                                  cat(K)



 NAME
      cat.exe - Schreibt Dateiinhalte bzw. die Eingabe zur Standard-Ausgabe.
      cat       (intern bish(K))

 SYNTAX
      cat  [-svtemnBT] [-] [ datei ... ]



 BESCHREIBUNG
      Das Kommando  cat  liest Dateiinhalte oder, wenn keine Dateien
      angegeben sind oder wenn ein - angegeben ist, von der Standard-Eingabe.
      Ausgabe erfolgt auf die Standard-Ausgabe.
      cat wird häufig dazu benutzt, mehrere Dateiinhalte hintereinander
      verkettet auszugeben, um eine Sammeldatei zu erzeugen.
      Daneben besitzt  cat  einige Filterfunktionen.

      Kommandozeilen-Optionen:

           -B     Dateien werden im Binär-Modus geöffnet. (Standard)
           -T     Dateien werden im Text-Modus geöffnet.
           -s     Unterdrückt Fehlermeldungen, wenn eine Datei nicht
                  geöffnet werden konnte.

           -v     Nichtabdruckbare Zeichen werden in sichtbare Zeichenfolgen,
                  bestehend aus zwei Zeichen, umgesetzt.
                  Die Zeichen mit den Dezimalwerten 1-26 (Ctrl-A bis Ctrl-Z),
                  mit Ausnahme von Tabulator, Seiten- und Zeilenvorschub,
                  werden in  ^A bis ^Z  umgesetzt.
                  Aus den Werten 27-31 entsteht:   ^[  ^\  ^]  ^^  ^_
                  Die Werte 127, 155 und 255 werden in eine Dezimalform
                  gewandelt:   \127, \155, \255
                  Die folgenden vier Optionen (-temn) werden ignoriert,
                  wenn diese Option -v nicht aktiviert ist.

           -t     TAB wird umgesetzt in  ^I
                  FF  wird umgesetzt in  ^L
           -e     Vor einen Zeilenvorschub wird  $  gesetzt.
           -m     Alle Zeichen >=128 werden in Dezimalform umgesetzt:  \ddd
           -n     Das Null-Zeichen wird per  \0  dargestellt.

      Die Optionen können in beliebiger Kombination und mittels einem
      oder mehrerer Argumente angegeben werden.
      Unbekannte Optionen werden ignoriert.

      Beim Lesen von der Standard-Eingabe, wenn die Tastatur damit verknüpft
      ist, kann die Eingabe mit <Ctrl>+<D> oder +<Z> beendet werden.



 BEISPIELE
      cat  d1 d2 d3 ...  >  Sammeldatei
      cat  d1 ...  >> datei
      cat  datei
      cat  > datei


 EXIT-CODE
      0     Keine Fehler.
      1     Bei fehlgeschlagenem Dateiöffnen.
      2     Bei sonstigen Fehlern.


 SIEHE AUCH
      bish(K)


 AUTOR
      Dieses Kommando  cat  wurde entwickelt von:
      Helmut Schellong, Bad Salzuflen



^

 crc(K)                                                                  crc(K)



 NAME
      crc.exe - Errechnet eine CRC-Prüfsumme
      crc       (Intern bish(K))

 SYNTAX
      crc  [ datei ... ]
      crc  < datei
      kdo | crc



 BESCHREIBUNG
      Das Kommando  crc  erzeugt eine CRC-Prüfsumme in Abhängigkeit
      von einer gelesenen Byte-Folge.
      (CRC = Cyclic Redundancy Check)
      Die Prüfsumme ist mit sehr hoher Wahrscheinlichkeit für jede
      Byte-Folge individuell verschieden, wenn die Byte-Folgen
      in irgendeiner Art Unterschiede aufweisen.
      Das Vertauschen zweier beliebiger Bytes untereinander in einer
      Datenmenge hat bereits eine andere Prüfsumme zur Folge.

      Die Prüfsumme ist eine 32-Bit-Zahl (bis 4.294.967.295) und wird
      als Dezimalzahl zur Standard-Ausgabe geschrieben.
      Bei Angabe von zwei oder mehr Dateien werden die Dateinamen
      vorangestellt.
      Ist keine Datei angegeben, liest crc von der Standard-Eingabe.
      Falls dabei die Eingabe mit einem Gerät verknüpft ist, kann
      der Lesevorgang durch Eingabe von ^D oder ^Z beendet werden.
      Bei dieser letztgenannten Eingabeart werden anhängende NL-Zeichen
      (Zeilenvorschübe) entfernt.



 EXIT-CODE
      0     Kein Fehler.
      2     Bei Fehlern von System-Funktionen.


 SIEHE AUCH
      bish(K), cmp(K).


 AUTOR
      Dieses Kommando  crc  wurde entwickelt von:
      Helmut Schellong, Bad Salzuflen



^

 cut(K)                                                                  cut(K)



 NAME
      cut.exe - Schneidet Zeichenbereiche/Spalten/Worte aus Zeilen heraus.
      cut       (intern bish(K))


 SYNTAX
      cut  -cListe                    [-BT] [ datei ... ]
      cut  -fListe [-d'char']    [-s] [-BT] [ datei ... ]
      cut  -fListe [-d'char...'] [-s] [-BT] [ datei ... ]
      cut  -lListe



 BESCHREIBUNG
      Das Kommando  cut  liest Dateiinhalte oder, wenn keine Dateien
      angegeben sind, von der Standard-Eingabe. Ausgabe erfolgt auf die
      Standard-Ausgabe.
      cut  selektiert beliebige Zeichenbereiche innerhalb von Zeilen.
      Für diese Aufgabe bietet  cut  drei verschiedene Arbeitsweisen.

      Kommandozeilen-Optionen:

           -cListe     Die in Liste angegebenen Zeichen werden ausgegeben.
                       (Listen-Syntax siehe unten.)
                       Diese Arbeitsweise ist zu vergleichen mit dem
                       Ausschneiden eines rechteckigen Längsstreifens
                       aus einem Blatt Papier.

           -fListe     Die angegebenen Felder werden ausgegeben.
           -d'c'       Trennzeichen zur Bildung der Felder ist 'c'.
                       Standardmäßig wird TAB eingesetzt.
                       Eine Zeile wird in 'anzahl_trennzeichen+1' Felder
                       aufgeteilt, wobei auch leere Felder gelten.
                       Wenn die Eingabe beispielsweise nur aus drei
                       Trennzeichen besteht, werden vier leere Felder
                       und die drei Trennzeichen ausgegeben.
                       Trennzeichen darf auch NL sein, womit eine Zeile
                       ein Feld bildet.
           -d'c...'    Wenn mehr als ein Trennzeichen angegeben wird,
                       ändert sich die Arbeitsweise dahingehend, daß
                       nur zusammenhängende Zeichenbereiche, bestehend
                       aus Nicht-Trennzeichen, als Felder aufgefaßt werden.
                       Für diesen Effekt können auch zwei gleiche Zeichen
                       angegeben werden:  -d'  '
                       Trennzeichen darf auch NL sein.
                       Bei mehr als einem Wort in der Ausgabe wird das
                       erste Zeichen im Trennzeichen-String als Worttrenner
                       eingefügt.
           -s          Unterdrückt Zeilen, die keine Trennzeichen enthalten.
                       Dies funktioniert nicht korrekt, wenn eine Zeile
                       mehr als 510 Zeichen hat.

           -lListe     Eine sortierte und möglicherweise minimierte Form
                       der Liste wird ausgegeben.

           -B          Dateien werden im Binär-Modus geöffnet. (Standard)
           -T          Dateien werden im Text-Modus geöffnet.

           Listen-Syntax:
           Um Zeichenbereiche zu definieren, muß eine Zahlenliste angegeben
           werden, gemäß folgender Syntax:

           a,b,c-d,e-f,g-,-j,-,m,n-o[,...]

           Die Liste muß dem jeweiligen Optionsbuchstaben direkt folgen.
           Eine Zahl rechts vom Bindestrich darf nicht kleiner als
           die linke Zahl sein.
           Zahlen vor und/oder nach dem Bindestrich können weggelassen
           werden, sie werden dann  als 1 bzw. als MAX  angenommen.
           MAX ist der größte positive Wert eines Maschinenwortes.
           Die Listenausdrücke -durch Kommata getrennt- dürfen bezüglich
           ihrer Zahlenwerte völlig unsortiert sein.
           Beliebige Zahlenbereichs-Überlappungen sind erlaubt. (ODER-Fktn.)
           Maximal 128 Listenausdrücke sind möglich.

      Die Zeilenlänge ist praktisch unbegrenzt; cut kann ohne weiteres
      das dreißigtausendste Feld aus einer Dateneinheit selektieren.
      Ein Zeilenvorschub (NL) oder Input-Ende beendet eine Dateneinheit.

      Bei Option -f kann ein NL-Zeichen auch als Trennzeichen definiert werden.
      Eine Spezial-Syntax für die Angabe von solchen Zeichen gibt es nicht.
      Möglichkeiten:   nl="`echo`";  cut -f... -d"$nl$nl" ...
                       nl="

                       "
                       cut -f... -d"$nl" ...

      Beim Lesen von der Standard-Eingabe, wenn die Tastatur damit verknüpft
      ist, kann die Eingabe mit <Ctrl>+<D> oder +<Z> beendet werden.



 BEISPIELE
      cut  -c4-23,29,51-62  datei
      cut  -f4-8 -d'  '     datei       # 4.-8. Wort aus allen Zeilen.
      cut  -f4-8 -d"$NL"    datei       # 4.-8. Zeile aus datei.
      cut  -f4-8 -d"$NL$NL" datei       # 4.-8. nichtleere Zeile aus datei.
      cut  -l1-3,5-11,4-7               # Ausgabe: '1-11'


 DIAGNOSE
      Fehlermeldung bei Syntax-Fehler.


 EXIT-CODE
      0     Keine Fehler.
      1     Bei fehlgeschlagenem Dateiöffnen.
      2     Bei sonstigen Fehlern.


 SIEHE AUCH
      bish(K)


 AUTOR
      Dieses Kommando  cut  wurde entwickelt von:
      Helmut Schellong, Bad Salzuflen



^

 echo(K)                                                                echo(K)



 NAME
      echo.exe - Liest Zeichenketten-Argumente und schreibt sie aus.
      echo       (intern bish(K))

 SYNTAX
      echo [ argument ... ]



 BESCHREIBUNG
      Das Kommando  echo  schreibt die erhaltenen Argumente
      jeweils durch ein Leerzeichen getrennt zur Standardausgabe.
      Zum Abschluß wird ein Zeilenvorschub zusätzlich ausgegeben.
      Die Argumente werden als Zeichenketten interpretiert.

      echo berücksichtigt die folgenden Spezial-Zeichenfolgen,
      wie sie in der Sprache C üblich sind, und noch weitere:
      (Jedoch wird \ durch % ersetzt.)

      %c     Unterdrückt den abschließenden Zeilenvorschub
             und bewirkt gleichzeitig einen Ausgabeabbruch.
      %e     <Escape>
      %z     <Control><Z>
      %s     "
      %t     Tab
      %r     Carriage return
      %n     Newline                           (Unter DOS: \r\n)
      %f     Form feed
      %b     Backspace
      %v     Vertikal-Tab
      %a     Beep
      %%     Prozent-Zeichen
      %'ZV'  Nach dem Zeilenvorschub (\n oder \r\n) folgende
             Leerzeichen und Tabs werden ignoriert.
      %0377  Octal-Zahl von 0 bis 0377, also aus 1 bis 4 Digits
             bestehend. Das erste Digit muß stets 0 sein.
             Hiermit können sämtliche Zeichen des Zeichensatzes
             dargestellt werden.

      Mit Hilfe dieses Kommandos kann man bekannte Daten ausgeben;
      Datenumlenkung (< > |) erweitert das Anwendungsspektrum.
      echo ist hilfreich bei der Fehlersuche und praktisch
      bei der Erzeugung kleiner Dateien.



 BEISPIELE
      echo " Eine 3½%"-1440K-Diskette hat $(([(80*2*18-33)*512]/BSZ)) Blöcke"
      echo "set HOME=c:\user\thorolf" >> c:\autoexec.bat

      Ausgabe für ein Menü:
           echo "%r%n
           Zu testendes Verzeichnis:  '$1'

           %tListendatei zur Liegenschaft :   l
           %tLiegenschaft zur Listendatei :   a
           %tHinweise                     :   ?
           %tDieses Menü verlassen        :   v
           %tBeenden                      :   e

           %t                             :   %c"
      Man beachte, daß das Argument für echo ("...") sich
      über mehrere Zeilen erstreckt, inklusive Zeilenvorschübe.

      Eingerücktes Schreiben:
           echo "aaa%
                 bbb%
                 ccc"
      Ausgabe:
           aaa
           bbb
           ccc
           _
      Die Leerzeichen/Tabs vor bbb und ccc werden ignoriert.
      Mit %r oder %b kann man 'folgenlos' dieses
      Ignorieren wieder abschalten.


 EXIT-CODE
      0     Kein Fehler aufgetreten.
      2     Wenn eine Systemfunktion einen Fehler meldete.

 SIEHE AUCH
      print(bish(K)), bish(I,...).

 AUTOR
      Dieses Kommando  echo  wurde entwickelt von:
      Helmut Schellong, Bad Salzuflen



^

 expr(K)                                                                expr(K)



 NAME
      expr.exe - Vergleicht Zeichenketten mit einem Vergleichsmuster.
      expr.exe - Ersetzt Zeichenkettenteile durch einen Ersatztext.
      expr       (intern bish(K))

 SYNTAX
      expr  zeichenkette  [xbvc=]:      RA  [[+=] ersatztext]
      expr  zeichenkette  [xbvc=]::     RA  [[+=] ersatztext]
      expr  zeichenkette  [xbvc=]:Name  RA  [[+=] ersatztext]
      expr  [offset[:länge]]variablenname  ...

      RA: Regulärer Ausdruck (Suchmuster)



 BESCHREIBUNG
      Dieses Kommando  expr  vergleicht Zeichenfolgen mit einem Suchmuster.
      Als Resultat dieser Bewertung reagiert expr mit einem entsprechenden
      Exit-Code und mit einer Ausgabe auf die Standard-Ausgabe
      oder einer Zuweisung an eine Shell-Variable.
      Wenn im zweiten Argument zwei Doppelpunkte (::) enthalten sind,
      erfolgt keine Ausgabe auf die Standard-Ausgabe.

      x    bewirkt die Verwendung von XRA (eXtra erweiterte RA; xregexp®).
      b    bewirkt die Verwendung von BRA (Basis RA).
           Diese Option hat Vorrang vor der Option -X der bish(K).
      v    ermöglicht die Angabe eines Variablennamens anstelle
           einer Zeichenkette 'zeichenkette' (Daten, s.o.).
           Direkt vor dem Namen können ein Offset-Wert und eine Länge plaziert
           werden, die sich auf den Inhalt der Variablen beziehen.
      c    Schaltet den internen Compilations-Cache ab.

      Bei Angabe von vier Argumenten ändert sich die Arbeitsweise,
      indem ein Ersatztext anstelle des zum Regulären Ausdruck
      passenden Zeichenkettenteils eingesetzt wird.
      Vor dem Ersatztext kann ein Steuerargument stehen:
           +      Es werden alle Vorkommnisse ersetzt.
                  Ohne diesen Schalter nur ein erstes.
           =      Spezialzeichen(folgen) im Ersatztext gelten als
                  gewöhnliche Zeichen.
           +=     Schalter + und = sind beide aktiv.
      Standard-Ausgabe unterbleibt bei Angabe von :: anstelle von :
      und ebenso bei der Zuweisung an 'Name'.
      Hinsichtlich der Syntax im Ersatztext (Substitution) siehe
      insbesondere xregexp®, und regexp®.

      Falls das zweite Argument vor : ein '=' enthält (=:), wird
      Groß- und Kleinschreibung nicht unterschieden, was jedoch
      bezogen auf Zeichenklasseninhalte ([...]) im RA nicht wirkt.

      Als Vergleichsmuster verarbeitet expr die von UNIX-Systemen her
      bekannten Regulären Ausdrücke (RA, siehe regexp®). Anstelle des
      Zeichens \ hat jedoch das Zeichen % die entsprechende Spezialbedeutung!
      (Mittels bish-Option -B oder 'set -B' kann \ geschaltet werden.)

      Ausgegeben wird die Anzahl derjenigen Zeichen aus der Zeichenkette,
      die zum RA passen - also die Länge einer Sub-Zeichenkette.
      Paßt keins, wird  0  ausgegeben, wobei der Exit trotzdem TRUE sein
      kann(!), wenn man beispielsweise als Anzahl >=0 ('c*') angibt
      und die Zeichenkette dadurch zum RA durchaus nicht unpassend ist.
      Der Exit hat Priorität und bewertet, ob der RA paßt oder nicht!

      Die Spezialvariable $. (Offset) wird bei passender Zeichenkette
      gesetzt, und zwar auf das erste passende Zeichen und gleichzeitig
      auf die Passenslänge.
                0123456789
           expr aaaabbbcc :: 'bbb' && echo $. $. $. $.
           4 3 -1 -1
           expr aaaabbbcc  :: 'a%(ab%)bb' && echo $. $. $. $.
           2 5 3 2
           expr aaaabbbcc x:: 'a(ab)bb' && echo $. $. $. $.
           2 5 3 2
           | | | +------- Länge  Einfassung
           | | +--------- Offset Einfassungsbeginn
           | +----------- Länge  match
           +------------- Offset match-Beginn
      Offset und Länge werden durch zweimaliges Lesen erlangt.
      Die Werte einer Einfassung werden anschließend geliefert.
      Weiteres Lesen liefert zunächst zwei weitere hier ungesetzte
      Werte und dann erneut die vier Werte.
      Shell-Option -O muß für diesen Wertedurchlauf gesetzt sein!
      Andernfalls wird immer nur der match-Beginn geliefert.
      Die Offset-Werte (und der Offset der Offset-Werte) werden nur
      bei vorliegendem match und dadurch Exit=0=true gesetzt.
      Der Argument-offset wird zum jeweiligen Offset hinzuaddiert!

      Diese Dokumentation beschreibt ansatzweise die BRA; die neuen XRA
      werden gar nicht erklärt. Siehe daher insbesondere xregexp®.
      Die Funktionsprinzipien dieses Kommandos  expr  sind allerdings nicht
      unterschiedlich zwischen BRA und XRA.

      Die Zeichenfolgen  %<  und  %>  passen zum Anfang bzw.
      zum Ende eines Wortes, mit der Zeichenmenge:  a-zA-Z_0-9
      Vor und nach dem Wort müssen Zeichen stehen, die nicht
      aus der angegebenen Zeichenmenge stammen.
      Diese beiden Zeichenfolgen repräsentieren keine Zeichen,
      sondern justieren auf eine Position, wie ^ und $ .

      Folgende Zeichenfolgen sind speziell:
           %a %A    Paßt / Paßt nicht zu  A-Za-z
           %l %L    Paßt / Paßt nicht zu  a-z
           %u %U    Paßt / Paßt nicht zu  A-Z
           %d %D    Paßt / Paßt nicht zu  0-9
           %w %W    Paßt / Paßt nicht zu  A-Za-z_0-9
           %!       Invertiert -vorangestellt- die vorstehenden Zeichenmengen.
      Die Häufigkeit kann mit  *  und  %{a,b%}  (nachfolgend)
      festgelegt werden.
      Bei einer Folge  %!%D  setzt %! auf Invertierung, und %D invertiert
      diese Invertierung, wobei %d diese nicht invertieren würde.
      Die Folge  %!%d  entspricht folglich %D, und  %!%D  entspricht %d.

      Mittels der Operatoren  %(  und  %)  kann ein Teil des RA
      oder auch der ganze RA eingefaßt werden.  In diesem Fall wird nicht
      die Anzahl der passenden Zeichen, sondern die Zeichen selbst ausgegeben.
      Und zwar diejenigen Zeichen der Zeichenkette, die zu der Einfassung
      beim RA passen - wenn der RA auch als ganzes paßt.
      Ein RA darf maximal neun solche Einfassungen %(...%) enthalten,
      nebeneinander und/oder verschachtelt.
      Mittels der Zeichenfolgen %1 bis %9 kann Bezug auf diese
      Einfassungen genommen werden, und zwar innerhalb des RA wie auch
      innerhalb des Ersatztextes.
      Bei einem zweiten Argument :: erfolgt keine Ausgabe.
      Im Ersatztext ist das Zeichen '&' speziell, welches den zum RA
      passenden Zeichenkettenteil einsetzt.  Maskierzeichen ist '%'.
      Im Ersatztext sind weiterhin die Zeichenfolgen  %U  %L  %E
      speziell, die auf Uppercase und Lowercase schalten, sowie diese Modi
      abschalten (%E).  Beispiel: "%U&%Ea$vx%L%2$kh"
      Bei Operator ':Name' wird in die benannte Shell-Variable geschrieben.

      Hinsichtlich der Syntax im Ersatztext (Substitution) siehe
      insbesondere xregexp®, und regexp®.

      Ein Zeilenvorschub wird nur angehängt, wenn Handle 1 mit dem Bildschirm
      verknüpft ist und wenn überhaupt (zuvor) ein Zeichen ausgegeben wurde.


 WARNUNG
      Reguläre Ausdrücke sollten standardmäßig maskiert ('RA') werden,
      damit unerwünschte Interpretation des Shell-Programms unterbleibt.


 BEISPIELE
      expr  $NAME : '.*'
           Liefert die Länge der Zeichenkette in der Shellvariablen NAME.
           (Einschließlich Zeilenvorschub.)

      expr  $NAME : '[^%r%n]*'
           Wie zuvor, jedoch ohne die Zeilenvorschub-Zeichen.

      expr  $PFAD : '.*\%(.*%)\.*'
      expr  $PFAD : '.*\%([^\]%{1,12%}%)\[^\]%{1,12%}$'
      expr  $PFAD : '.*\%([A-Za-z.]%{1,12%}%)\[A-Za-z.]%{1,12%}$'
      expr  $PFAD : '.*\%([A-Z]%{1,8%}%.[A-Z]%{1,3%}%)\[A-Z.]%{1,12%}$'
           Geben den letzten Verzeichnisnamen eines Pfadnamens aus.
           Unterschiedlicher Eingrenzungsgrad.


 NOTA
      Das bish-interne expr-Kommando hat erhebliche Geschwindigkeitsvorteile.
      Häufiges Aufrufen hat diesbezüglich nicht die Nachteile von expr.exe.

      Das von UNIX-Systemen her bekannte externe Kommando  expr  hat
      zusätzliche Funktionalitäten, wie Berechnung und Vergleiche von
      arithmetischen Ausdrücken und Test von leeren/nichtleeren Strings.
      Diese Funktionalitäten werden von anderen bish-internen Kommandos
      (let, test) in besserer Form zur Verfügung gestellt, weshalb bei
      dem hier beschriebenen expr-Kommando darauf verzichtet wurde.

      Das Fixierzeichen ^ ist NICHT implizit im RA enthalten ('^...').


 EXIT-CODE
      0     Der Vergleich beider Ausdrücke ergab Übereinstimmung.
            (Auch wenn aus %(...%) nichts ausgegeben wurde.)
      1     Die Ausdrücke passen nicht zueinander.
      2     Fehler bei Offset oder Datenlänge (v).
      3     Bei (Syntax-)Fehlern.

 SIEHE AUCH
      bish(K), regexp®, xregexp®, grep(K), test(K).

 AUTOR
      Dieses Kommando  expr  wurde entwickelt von:
      Helmut Schellong, Vlotho
      Copyright © 1995-2018



^

 grep(K)                                                                grep(K)



 NAME
      grep.exe - Prüft Zeilen auf Übereinstimmung mit einem Suchmuster
      grep       (intern bish(K))

 SYNTAX
      grep  [ -BXFSVAchlm[n]nsviyLxq1 ] [Vname] [-e] RA      [ datei ... ]
      grep  [ -BXFSVAchlm[n]nsviyLxq1 ] [Vname] { -e RA }... [ datei ... ]

      RA: Regulärer Ausdruck (Suchmuster)



 BESCHREIBUNG
      Das Kommando  grep  durchsucht Dateien nach Zeilen, die mit einem
      Suchmuster übereinstimmen und schreibt diese Zeilen zur Standard-Ausgabe.
      Wenn keine Dateien angegeben werden, liest grep von der Standard-Eingabe,
      sofern diese nicht mit einem Terminal (tty) verknüpft ist.
      Bei mehr als einer Datei wird jeder Zeile der zugehörige Dateiname
      vorangestellt.
      Als Suchmuster verarbeitet grep die von UNIX-Systemen her bekannten
      Regulären Ausdrücke (RA, siehe regexp®). Anstelle des Zeichens \
      hat jedoch das Zeichen % die entsprechende Spezialbedeutung!
      Innerhalb der bish(K) kann per 'set -B' das Zeichen \ gewählt werden.
      Mittels 'set +B' kann wieder auf % zurückgestellt werden.
      Und innerhalb eines RAs können neben %n auch %r, %t und %z als Ersatz
      für die Zeichen NL, CR, TAB und ^Z verwendet werden (auch zwischen []).

      Diese Dokumentation beschreibt ansatzweise die BRE, die neuen XRE
      jedoch gar nicht; siehe dazu xregexp®.

      grep  berücksichtigt folgende Kommandozeilen-Optionen:

           -B     Es werden BRA (Basis-RA) verwendet (Default).
                  Dies hat Vorrang vor der bish-Option '-X'.

           -X     Es werden XRA (eXtra erweiterte Reguläre Ausdrücke)
                  anstelle der BRA (Basis RA) verwendet.

           -F     Kein Zeichen des Suchmusters hat spezielle Bedeutung.
                  Das Suchmuster wird nicht als RA interpretiert.
                  Die Funktion entspricht dem Kommando 'fgrep'.

           -S     Die Vergleichsrichtung bei den Zeichenketten
                  wird umgedreht (Swap: a in b <--> b in a).
                  Ist nur bei -F wirksam.

           -V     Ausgabe erfolgt in eine Variable 'Vname'.
                  Es wird die Anzahl der passenden Zeilen eingetragen.
                  Bei mehreren Dateien wird nur der Wert der
                  letzten Datei eingetragen.
                  Insofern ist diese Option nur bei einer einzigen
                  angegebenen Datei oder beim Lesen von der
                  Standard-Eingabe sinnvoll.

           -x     Zeile und Suchmuster müssen komplett gleich sein.
                  (Option -F wird als gesetzt angenommen.)

           -e     Falls ein RA mit dem Minuszeichen (-) beginnt.
                  (Konflikt mit der Optionen-Schreibweise!)
                  Oder falls mehrere RA angegeben werden.
                  Es können maximal 8 '-e RA' angegeben werden.
                  Bei zwei oder mehr angegebenen RA wird jede
                  Zeile entsprechend oft untersucht, bis ein
                  eventuelles Passen (match) auftritt.
                  Es handelt sich um eine Oder-Funktion.
                  Eine Und-Funktion ist wählbar (-A).

           -A     Es können bis zu 8 '-e RA' angegeben werden,
                  für die nun jedoch eine Und-Funktion gilt.

           -c     Anstelle des Inhalts passender Zeilen
                  wird deren Anzahl (pro Datei) ausgegeben.

           -h     Verhindert die Ausgabe von Dateinamen.

           -l     Es werden nur Dateinamen ausgegeben,
                  und zwar ggf. auch bei nur einem angegebenen Namen.
                  Die Optionen -c und -h sind hierbei unwirksam.

           -m[n]  Es werden maximal n passende Zeilen ausgegeben.
                  Voreingestellt ist n=1.
                  (Diese Option hat Vorrang über -c)

           -L     Nur die letzte passende Zeile wird ausgegeben.
                  Diese Option ordnet sich den anderen unter und
                  unterdrückt -mit Ausnahme der letzten- die Ausgabe
                  aller Zeilen.
                  Bei dieser Option wird eine Zeile mit mehr als
                  32 KB auf diese Länge gekürzt.

           -n     Passenden Zeilen wird deren Nummer vorangestellt.

           -s     Unterdrückt Fehlermeldungen über Dateien, die nicht
                  geöffnet werden konnten.

           -v     Invertiert die Arbeitsweise;
                  nicht-passende Zeilen gelten als übereinstimmend.

           -i
           -y     Groß-/Kleinschreibung wird ignoriert.
                  Das gilt nicht für äöü(ÄÖÜ); hier muß man
                  gegebenenfalls Zeichenklassen ([Ää]) angeben.

           -q     (=quiet)
           -1     Standard-Ausgabe wird unterdrückt.


 WARNUNG
      grep  unterstützt eine maximale Zeilenlänge von 1 MB.
      grep  arbeitet zeilenorientiert; es wird ein Datenstrom
      mit Zeilenvorschüben verlangt.
      Reguläre Ausdrücke sollten standardmäßig maskiert ('RA') werden,
      damit unerwünschte Interpretation des Shell-Programms unterbleibt.


 BEISPIELE
      grep  '^ [A-Z].*[A-Z0-9]$' grep.mnk
           Liefert die Gliederungsüberschriften dieser Datei: NAME
                                                              SYNTAX
                                                              BESCHREIBUNG
                                                              ...
                                                              AUTOR
      grep  -l  'N[oO][lL][aA][hH]%{0,1%} %{1,2%}GmbH'  *.txt
           Liefert die Namen derjenigen Dateien im aktuellen Verzeichnis,
           die den Firmennamen 'Nolah GmbH' enthalten, und zwar
           klein- oder großgeschrieben, mit oder ohne 'h' am Ende,
           und mit ein oder zwei Leerzeichen zwischen den beiden
           Worten.
           In der Praxis braucht man meistens nicht so stark eingrenzen;
           folgender Ausdruck führt auch zum Ziel:  'N[oO][lL][aA]..*GmbH'

      edit  ` grep -l '\[A-Z]%{1,%}\CERA\[A-Z]%{1,%}' *.LST *.TXT `
           Ruft einen Editor auf, mit allen Dateien im Verzeichnis als
           Argumente, die mit LST oder TXT enden und die gleichzeitig
           mindestens einen dreigliederigen Pfadnamen enthalten, dessen
           zweite Komponente CERA lautet und dessen andere Komponenten
           mindestens einen Großbuchstaben A-Z enthalten.


 NOTA
      Das bish-interne grep-Kommando hat Geschwindigkeitsvorteile.
      Häufiges Aufrufen hat diesbezüglich kaum Nachteile
      gegenüber einem Aufruf mit vielen Dateinamen.
      Es kann eine außerordentlich lange Dateinamenliste angegeben werden.

      In der bish können Kommandos in eine Oder-Kette gestellt werden:
      In etwa 20 Jahren wurde einmal  grep &| grep &| grep  und etwa
      5-mal  grep &| grep  programmiert.
      Daraus ist ersichtlich, daß 8-mal '-e RA' ausreichen sollte.


 EXIT-CODE
      0     Mindestens eine Zeile wurde als zutreffend bewertet.
      1     Keine Zeile wurde als zutreffend bewertet.
      2     Bei (Syntax-)Fehlern.

 SIEHE AUCH
      bish(K), xregexp®, regexp®, expr(K)

 AUTOR
      Dieses Kommando  grep  wurde entwickelt von:
      Helmut Schellong, Vlotho
      Copyright © 1995-2016



^

 bgrep(K)                                                              bgrep(K)



 NAME
      bgrep.exe - Durchsucht Dateien nach einer Byte-Folge
      bgrep       (intern bish(K))


 SYNTAX
      bgrep  [-gclihstvqM] [name] [-oN|-ON] [-nN]  [-f]Folge  datei ...
      bgrep  [-gclihstvqM] [name] [-oN|-ON] [-nN]  -Fdatei  datei ...
      bgrep  [-gclihstvqM] [name] [-oN|-ON] [-nN]  -Vname  datei ...

      N:  #[{b|k|w|l}][{x|+}#[{b|k|w|l}]]...[{x|+|-}#[{b|k|w|l}]]
      #:  [0]...{1-9}...[0-9]...



 BESCHREIBUNG
      Das Kommando  bgrep  liest eine oder mehrere Dateien
      und sucht dabei nach Vorkommnissen einer Folge von Bytes.
      Die Byte-Folge kann in der Kommandozeile angegeben werden
      oder wird aus einer Datei gelesen, wobei alle Werte von 0 bis 255
      gültig sind und nötigenfalls per '\ddd' oder '\xhh' geschrieben
      werden können.
      Wenn keine Datei angegeben wurde, liest bgrep von der Standard=
      eingabe, falls diese nicht mit einer Tastatur verknüpft ist,
      wobei dann die Optionen -oO ignoriert werden.
      Standardmäßig wird die Byte-Nummer (>=0) der ersten Fundstelle
      zur Standardausgabe geschrieben. Bei mehr als einer angegebenen
      Datei wird der Dateiname jeweils vorangestellt:  'name:  nummer'
      bgrep (binary grep) verarbeitet keine 'regulären Ausdrücke',
      und ähnelt damit 'fgrep'.


      bgrep  berücksichtigt die folgenden Kommandozeilen-Optionen:

      -g      Es werden alle Vorkommnisse gemeldet,
              anstatt nur des (jeweils) ersten.

      -c      Anstelle der Byte-Nummer(n) wird die
              Anzahl der Fundstellen (>=0) ausgegeben.

      -l      Es werden die Namen nur derjenigen Dateien mit
              mindestens einer Fundstelle ausgegeben.

      -i      Wirkt mit vorstehender Option -l zusammen:
              Es werden die Namen nur derjenigen Dateien
              ohne Fundstelle ausgegeben.

      -h      Das Voranstellen der Dateinamen(:) wird abgeschaltet.

      -s      Fehlermeldungen (+Exit), bezüglich von Dateien,
              die nicht geöffnet werden konnten, unterbleiben.

      -v      Es muß ein Variablenname 'name' angegeben werden.
              Dorthinein wird die Byte-Nummer der Fundstelle oder
              die Anzahl der Fundstellen geschrieben.
              Nach einem Schreiben wird nochmaliges Schreiben gesperrt.

      -q      Mittels dieser Option wird jeder Schreibvorgang
              zur Standardausgabe unterdrückt.
              Es verbleibt der Exit-Wert zur Auswertung, und die
              Ausgabe in eine Variable.

      -M      Es wird Memory-Mapping mmap() benutzt.
              Diese UNIX-Lesemethode ist um etwa 20% schneller.

      -o      Diese Optionen dienen zur Angabe eines Offsets.
      -O      Bei -O  werden die Byte-Nummern ab Offset gezählt,
              während bei -o  die absoluten Dateiadressen ausgegeben
              werden.
              Es kann eine Dezimalzahl in einfacher Form oder ein
              arithmetischer Ausdruck angegeben werden (s.unten).

      -n      Es werden nicht mehr Bytes durchsucht als mit dieser
              Option angegeben wurden.

      -t      Konversionen für die Optionen -F -V -f .

      -F      Die Byte-Folge, nach der gesucht werden soll, wird
              einer angegebenen Datei entnommen.
              Durch -t wird eine Konversion (\ddd\xhh) vorgenommen.
              Anhängende  \r\n^Z  werden entfernt - man kann
              ggf. stattdessen \13\10\26 schreiben.

      -V      Die Byte-Folge, nach der gesucht werden soll, wird
              einer angegebenen Variable 'name' entnommen.
              Durch -t wird eine Konversion (\ddd\xhh) vorgenommen.

      -f      Muß verwendet werden, falls die Byte-Folge mit einem
              Minus-Zeichen (-) beginnt.
              Durch -t wird die Konversion (\ddd\xhh) abgeschaltet;
              auch ohne -f .

      Optionswerte müssen dem Optionsbuchstaben ohne Zwischenraum folgen.
      Die Optionen können in beliebiger Reihenfolge angegeben werden;
      oOnfFnNe  dürfen aber nicht mit den anderen kombiniert werden.
      Optionen -c und -l löschen sich gegenseitig, -l löscht -g .

      Arithmetischer Ausdruck für 'n':
              Beispiel:   -o33bx4x15+1200+25-3l
              entspricht  -o1014973
              x  ist ein Multiplikations-Operator.
              b  entspricht  x512
              k  entspricht  x1024
              w  entspricht  x2
              l  entspricht  x4

      Spezielle Umwandlungen bei der Byte-Folge:
      Nach einem Zeichen '\' wird eine Dezimalzahl aus ein bis drei
      Digits 0-9 in ein Byte mit dem entsprechenden Wert umgewandelt.
      Nach den Zeichen '\x' wird eine Hexadezimal-Zahl aus ein bis zwei
      Hex-Zeichen 0-9a-fA-F in ein Byte umgewandelt.
      Jedes erste Zeichen '\' wird entfernt, woraus folgt, daß zwei
      dieser Zeichen (\\) geschrieben werden müssen, damit eins resultiert.
      '\x' wird ebenfalls grundsätzlich entfernt.


      bgrep  berücksichtigt die folgenden Umgebungsvariablen (Environment):
      BGREPAUTOR
        Um die Autorenmeldung abzuschalten:
        BGREPAUTOR=H.Schellong,Vlotho
      BGREPPROGRAM
        Um die Freeware-Meldung zu unterdrücken:
        BGREPPROGRAM=Freeware_nur_fuer_nichtgewerbliche_Verwendung
        (BGREPAUTOR muß hierfür auch gesetzt sein.)
      Dies gilt nicht für das bish-interne bgrep.



 WARNUNGEN
      Bei arithmetischen Ausdrücken sollte ein Minuszeichen gegebenenfalls
      nur vor der letzten Zahl stehen. Sonst gibt es unerwartete Resultate.
      bgrep  benutzt lseek() bei Offset-Angabe >0. Dies sei gesagt im
      Hinblick auf Dateien, die nicht seek-bar sind. bgrep ist hier nicht
      so vielseitig ausgestattet wie dd(K).

 HINWEISE
      Die maximale Länge für die (resultierende) Byte-Folge
      beträgt 4096.
      Das Kommando arbeitet äußerst schnell und benötigt auf einem
      Pentium60 unter Unix nur etwa 0.07 Sekunden user-/sys-time pro MB.
      bgrep -c .text 360k-Datei           27 msec
      fgrep -c .text 360k-Datei          160 msec
       grep -c .text 360k-Datei         3340 msec
       grep -c .text 360k-Datei          390 msec (bish-intern-grep)
      (170 Vorkommnisse ".text")


 DIAGNOSE
      Fehlermeldungen zur Standard-Fehlerausgabe.

 EXIT-CODE
      0     Byte-Folge mindestens einmal gefunden.
      1     Byte-Folge nicht gefunden.
      2     Fehlerhafte Argumentliste.
      3     Dateiöffnen fehlgeschlagen.
      4     Fehler beim Dateilesen.


 SIEHE AUCH
      grep(K), bish(K), hx(K), dd(K), cmp(K).


 AUTOR
      Dieses Kommando  bgrep  wurde entwickelt von:
      Helmut Schellong, Vlotho
      Copyright © 1995-2016





^

 line(K)                                                                line(K)



 NAME
      line.exe - Gibt selektierte Zeilen aus
      line       (intern bish(K))

 SYNTAX
      line  [ {-|+}a[-[e]] ] [ datei ... ]



 BESCHREIBUNG
      Das Kommando  line  liest Dateiinhalte und schreibt selektierte
      Zeilen auf die Standard-Ausgabe.
      Sind keine Dateien angegeben, liest line von der Standard-Eingabe.
      Sind keinerlei Argumente angegeben und ist die Standard-Eingabe
      mit der Tastatur verknüpft, liest line eine einzelne Zeile (-1).

      Mit der Kommandozeilenoption  a-e  kann eine Zeile oder ein
      Zeilenbereich ausgewählt werden:
           -n        z.B. -4
           -a-e      z.B. -5-45
           -a-       a - 2^31-1
           +a        alle Zeilen außer a
           +a-e      alle Zeilen außer a-e
      Voreingestellt ist  -1-10 .
      Bei einem vorangestellten Pluszeichen wird die Arbeitsweise
      invertiert:  nicht angegebene Zeilen werden ausgegeben.
      Bei fehlendem Endwert ([e]) wird 'quasi-unendlich' eingesetzt.

      Die Listen-Syntax des Kommandos cut(K) ist wesentlich komfortabler.
      Dies sei gesagt, weil man mit  cut  ähnliche Aufgaben lösen kann.

      Zeilen mit mehr als 1536 Zeichen werden zerstückelt.



 BEISPIEL
      zeile="`line`"        Liest eine Zeile 'raw' - anders als 'read'.

 EXIT-CODE
      0     Kein Fehler.
      2     Fehler von Systemfunktion.

 SIEHE AUCH
      bish(K), cut(K), rel(K), readc(K), read(bish(K)).

 AUTOR
      Dieses Kommando  line  wurde entwickelt von:
      Helmut Schellong, Bad Salzuflen



^

 wc(K)                                                                    wc(K)



 NAME
      wc.exe - Zählt Zeilen, Worte und/oder Zeichen, oder Längen.
      wc       (intern bish(K))

 SYNTAX
      wc  [-lwcm] [ datei ... ]



 BESCHREIBUNG
      Das Kommando  wc  liest Dateiinhalte oder, wenn keine Dateien
      angegeben sind, von der Standard-Eingabe.
      Ausgabe der gezählten Werte erfolgt auf die Standard-Ausgabe.
      Zugehörige Dateinamen werden nach den Zahlen ausgegeben,
      falls mehr als eine Datei angegeben wurde.
      Bei zwei oder mehr Dateien werden abschließend die Summenwerte
      ausgegeben.
      Tastatur-Eingabe kann mit ^D oder ^Z beendet werden.

      Kommandozeilen-Optionen:
           -l     Anzahl Zeilen wird ausgegeben.
           -w     Anzahl Worte wird ausgegeben.
           -c     Anzahl Zeichen wird ausgegeben.
           -m     Maximale Längen von Zeilen und/oder Worten
                  werden ausgegeben.
                  Zeilenendezeichen werden mitgezählt.
                  Option -c bewirkt hier die Ausgabe der Anzahl
                  von verschiedenen Zeichen.

      Die Optionen können in beliebiger Kombination und mittels
      ein bis vier Argumenten angegeben werden; unbekannte werden ignoriert.
      Standard-Einstellung ist  -lwc .

      Die der Wortisolierung zugrunde liegenden Trennzeichen sind:
           Leerzeichen, Tab und Zeilenvorschub.
      Bei der bish-internen Version ist dies der Inhalt von IFS.

      Eine unvollständige Zeile am Dateiende (ohne Zeilenvorschub)
      wird berücksichtigt.
      Zeilenvorschübe werden also als Zeilentrenner bewertet.



 BEISPIELE
      ANZAHLWORTE=`echo $ARRAY | wc -w`
      ARRAYGRÖßE=`echo "$ARRAY%c" | wc -c`

      DATEIGRÖßE=`cat $DATEI | wc -c`
      DATEIGRÖßE=`wc -c $DATEI`

      wc -l  datei


 EXIT-CODE
      Ungleich 0 bei Fehlern.


 AUTOR
      Dieses Kommando  wc  wurde entwickelt von:
      Helmut Schellong, Bad Salzuflen



^

 cmp(K)                                                                  cmp(K)



 NAME
      cmp.exe - Vergleicht Dateiinhalte byte-weise
      cmpf      (intern bish(K))

 SYNTAX
      cmpf  [-q]  datei1 datei2  [offs1 [offs2]]



 BESCHREIBUNG
      Das Kommando  cmpf  vergleicht byte-weise die Inhalte zweier Dateien.
      Bei Ungleichheit wird die entsprechende (erste) byte-Adresse
      als Dezimalzahl zur Standard-Ausgabe geschrieben.
      Bei Gleichheit aber unterschiedlichen Dateigrößen wird
      das Wort "SIZE" ausgegeben.

      Die Kommandozeilen-Option -q unterdrückt Ausgaben
      auf die Standard-Ausgabe.
      In diesem Fall verbleibt nur der Exit-Code (s.u.) zur Auswertung.

      Bei Angabe von Offset-Werten (offs1,offs2) werden die zugehörigen
      Dateien nicht auf Anwendbarkeit geprüft; die Systemfunktion lseek()
      wird etwaige Fehler melden.
      Eine Prüfung per Kommando 'test|[..]' ist die bessere Lösung.

      cmpf  berücksichtigt die folgenden Umgebungsvariablen (Environment):
      BSHAUTOR
        Um die Autoren-Meldung zu unterdrücken:
        BSHAUTOR=H.Schellong,Vlotho
      CMPPROGRAM
        Um die Freeware-Meldung zu unterdrücken:
        CMPPROGRAM=Freeware_nur_fuer_nichtgewerbliche_Verwendung
        (BSHAUTOR muß hierfür auch gesetzt sein.)
      Nicht gültig bish-intern.



 BEISPIELE
      cmpf  datei1 datei2
      cmpf  -q vers vers_ || { cmp_status=$?; goto NOTEQ; }


 DIAGNOSE
      Fehler-Beschreibungen zur Standard-Fehlerausgabe.

 EXIT-CODE
      0     Bei Gleichheit der Dateien.
      1     Bei Ungleichheit der Dateien.
      2     Bei Fehlern von System-Funktionen.
      5     Bei Gleichheit aber unterschiedlichen Dateigrößen.
      8     Bei fehlerhafter Argumentliste.


 SIEHE AUCH
      bish(K), fstat, test(K), crc(K), sha256(K), sha512(K).


 AUTOR
      Dieses Kommando  cmpf  wurde entwickelt von:
      Helmut Schellong, Vlotho
      Copyright © 1995-2016



^

 rel(K)                                                                  rel(K)



 NAME
      rel.exe - Entfernt gleiche Zeilen  (remove equal lines)
      rel       (intern bish(K))

 SYNTAX
      rel  [ arg ... ]  [ < datei1 ]  [ > datei2 ]
      ... | rel [ arg ... ] | ...



 BESCHREIBUNG
      Das Kommando  rel  ist ein typisches Filter-Kommando, das von der
      Standard-Eingabe liest und auf die Standard-Ausgabe schreibt.
      Aufeinanderfolgende gleiche Zeilen werden -bis auf eine- entfernt.
      Das gilt auch für Leerzeilen.
      Falls Argumente angegeben sind, werden auch Zeilen entfernt, die
      damit gleich sind - und zwar alle solche Zeilen.

      Tastatur-Eingabe kann mit ^D oder ^Z beendet werden.



 EXIT-CODE
      0     Kein Fehler.
      2     Fehler von Systemfunktion, u.a.

 SIEHE AUCH
      bish(K), cut(K), line(K).

 AUTOR
      Dieses Kommando  rel  wurde entwickelt von:
      Helmut Schellong, Vlotho
      Copyright © 1996-2016



^

 tr(K)                                                                    tr(K)



 NAME
      tr.exe - Umsetzen, Löschen und Reduzieren von Zeichen(folgen).
      tr       (intern bish(K))

 SYNTAX
      tr  [-cds] [ string1 [ string2 ] ]



 BESCHREIBUNG
      Das Kommando  tr  ist ein typisches Filterkommando.
      tr liest von der Standard-Eingabe und schreibt auf die Standard-Ausgabe.
      Häufigste Verwendung ist die Umsetzung der Zeichen in string1
      in die korrespondierenden Zeichen in string2.
      Die Möglichkeiten gehen allerdings insgesamt weit über diese
      einfache Funktion hinaus.
      Tastatur-Eingabe kann mit ^D oder ^Z beendet werden.

      Kommandozeilen-Optionen:

           -c     Die Zeichenmenge in string1 wird komplementiert.
                  Es werden diejenigen Zeichen als in string1 angegeben
                  angenommen, die NICHT angegeben wurden.
                  Grundlage dafür ist der gesamte Zeichensatz.
                  tr verarbeitet sämtliche Zeichen von dezimal 0 bis 255.

           -d     Aus dem Eingabestrom werden diejenigen Zeichen entfernt,
                  die in string1 angegeben sind.  Option -c wirkt vorher.

           -s     Mit Wirkung auf den Ausgabestrom wird von den in
                  string2 angegebenen Zeichen eine Folge von gleichen
                  Zeichen auf ein einzelnes Zeichen reduziert.
                  In der Ausgabe können also nicht zwei oder mehr gleiche
                  Zeichen hintereinander auftauchen, die in string2
                  angegeben wurden.

           Die Optionen können nur per folgender Formen angegeben werden:
                -c  -d  -s  -cd  -cs  -ds  oder  -cds
           Und zwar, damit keine besonderen Maßnahmen nötig sind, falls ein
           string mit - beginnt.
           Beispielsweise  -dcs und -cdss  werden als string interpretiert.

      String-Syntax:
           Innerhalb der strings werden folgende Sequenzen verarbeitet:

           [a-z][A-Z][z-a]   Kurzform für Zeichenbereiche.
                             Umdrehungen sind also auch hier möglich.
           [c*n]             Die Anzahl des Zeichens c wird durch
                             n angegeben. Sinnvoll in string2.
                             Bei n=0 oder fehlendem n wird eine maximale
                             Anzahl angenommen.  n wird dezimal bewertet.
           \d  \dd  \ddd     Außerhalb der [...] und innerhalb an den
                             Positionen  a, z und c
                             können nach \ ein bis drei Digits
                             als Dezimalzahl angegeben werden.
                             Ein Nicht-Digit beendet; nötigenfalls kann
                             mit führenden Nullen erweitert werden.
           \                 Maskierzeichen.
                             Hebt die Spezialbedeutung von \ und [ auf.
                             Die Zeichen  - * ]  sind allein durch ihre
                             Position nach [ speziell.

           Die resultierenden string-Längen dürfen unterschiedlich sein.
           Bei Länge 256 wird gekappt.
           Bei Option -c ist die Position der Komplement-Zeichen natürlich
           nicht explizit angebbar.



 BEISPIELE
      Kleinbuchstaben in Großbuchstaben umwandeln:

           tr "[a-z]äöü" "[A-Z]ÄÖÜ" <datei1 >datei2

      Soviel Punkte werden ausgegeben, wie Zeilen in der Datei sind:

           tr  -cd \10 <datei | tr \10 .

      Entfernt alle Leerzeilen, außer einer ersten:

           tr  -s '' \10  <datei

           tr  -s \13 \10  b<datei       (DOS: \r werden allerdings gelöscht.)
           tr  -s  '' \10  t<d1 t>d2     (DOS)

      Beläßt nur alphanumerische, deutsche Worte in den Zeilen;
      die entstehenden Zeilen können weiterverarbeitet werden:

           tr  -cs '[a-z]äöüß[A-Z]ÄÖÜ[0-9]\13\10' '[ *]'  <datei

      Alle Zeichen werden in '\0' umgesetzt (demonstriert -c ''):

           kdo1 | tr  -c '' '[\0*]' | kdo3

      Alle $-Zeichen aus datei werden in @-Zeichen umgesetzt und
      dann alle '\0'-Zeichen in $-Zeichen und Ausgabe zum Bildschirm:

           tr '$' '@' <datei | tr '\0' '$'

      Ein Wort pro Zeile:

           tr  -cs '[a-z][A-Z][0-9]' '[\10*]' <datei1 >datei2

      Aus dem beliebigen Inhalt von datei1 werden alle alphanumerischen
      Zeichenfolgen extrahiert und ein Wort pro Zeile an datei2 ausgegeben.
      Alle nicht-alphanumerischen Zeichen werden in Zeilenvorschübe
      umgewandelt. Durch Option -s wird maximal ein NL hintereinander
      ausgegeben.
      So kann man bespielsweise aus einer Binär-Datei alle lesbaren
      Zeichenfolgen gewinnen. Von Nachteil ist dabei, daß nach diesem
      einen Verarbeitungsschritt auch Worte aus nur ein bis zwei Zeichen
      ausgegeben werden.


 DIAGNOSE
      Fehlermeldung bei string-Syntaxfehlern.


 EXIT-CODE
      0     Kein Fehler aufgetreten.
      2     Bei Fehler einer Systemfunktion.


 AUTOR
      Dieses Kommando  tr  wurde entwickelt von:
      Helmut Schellong, Bad Salzuflen



^

 test(K)                                                                test(K)



 NAME
      test.exe - Bewertet Ausdrücke und reagiert mit dem Exit-Code
      [.exe
      test, [, [[     (intern bish(K))

 SYNTAX
      test  ausdruck
      [ ausdruck ]
      [[ ausdruck ]]



 BESCHREIBUNG
      Das Kommando  test  wertet die erhaltenen Argumente aus
      und reagiert mit einem entsprechenden Exit-Code.
      Die Argumente bilden insgesamt einen Ausdruck, bestehend
      aus Zeichenketten und Operatoren und müssen durch Leerzeichen
      oder Tabs voneinander getrennt werden, was auch bei einem
      Aufruf per Spezialsyntax-Zeichen ( [ ] , [[ ]] ) für diese gilt.
      Die Abschlußargumente ] bzw. ]] müssen in diesen Fällen
      vorhanden sein.
      Ohne Argument liefert test einen FALSE Exit-Code.
      Achtung, TRUE = 0  und  FALSE = 1  !

      test verarbeitet die folgenden Elementar-Ausdrücke, die
      mittels der weiter unten beschriebenen Operatoren beliebig
      zu einem Gesamtausdruck zusammengestellt werden können:

      -e datei          TRUE wenn datei existiert.
      -r datei          TRUE wenn datei () lesbar ist.
      -w datei          TRUE wenn datei () beschreibbar ist.
      -x datei          TRUE wenn datei () ausführbar ist.
      -f datei          TRUE wenn datei () eine normale Datei ist.
      -d datei          TRUE wenn datei () ein Verzeichnis ist.
      -c datei          TRUE wenn datei () ein Zeichen-Gerät ist.
      -s datei          TRUE wenn datei () nicht leer ist.
      -t handle         TRUE wenn handle mit einem Gerät verbunden ist.

      Die Klammern () stehen für "existiert und".
      UNIX:
      -b datei          TRUE wenn datei () ein Block-Gerät ist.
      -p datei          TRUE wenn datei () eine FIFO(named pipe) ist.
      -h datei          TRUE wenn datei () ein symbolischer Link ist.
      -L datei          TRUE wenn datei () ein symbolischer Link ist.
      -u datei          TRUE wenn datei () set_uid gesetzt hat.
      -g datei          TRUE wenn datei () set_gid gesetzt hat.
      -k datei          TRUE wenn datei () sticky-bit gesetzt hat.
      -H datei          TRUE wenn datei () ein semaphore ist.
      -M datei          TRUE wenn datei () shared memory ist.
      -S datei          TRUE wenn datei () ein Socket ist.
      -O datei          TRUE wenn datei () uid gleich eff. process-uid ist.
      -G datei          TRUE wenn datei () gid gleich eff. process-gid ist.

      datei1 -nt datei2          TRUE wenn datei1 neuer ist als datei2.
      datei1 -ot datei2          TRUE wenn datei1 älter ist als datei2.
      datei1 -ef datei2          TRUE wenn beide dateien auf dem selben
                                 Laufwerk sind.
      -z string         TRUE wenn string ein Leerstring ist.
      -n string         TRUE wenn string kein Leerstring ist.
      string            TRUE wenn string kein Leerstring ist.
      str1 =  str2      TRUE wenn die Zeichenketten gleich sind.
      str1 == str2      TRUE wenn die Zeichenketten gleich sind.
      str1 != str2      TRUE wenn die Zeichenketten ungleich sind.
      str1 =  pattern   TRUE wenn str1       zum pattern paßt. (nur bei [[ ]])
      str1 == pattern   TRUE wenn str1       zum pattern paßt. (nur bei [[ ]])
      str1 != pattern   TRUE wenn str1 nicht zum pattern paßt. (nur bei [[ ]])
      str1 >  str2      TRUE wenn str1 größer als str2 ist.
      str1 <  str2      TRUE wenn str1 kleiner als str2 ist.

      n1 -eq n2         TRUE wenn die Zahlen algebraisch gleich sind.
      -ne -gt -ge -lt und -le  stehen ebenfalls zur Verfügung.
      (!=  >   >=  <       <=)
      Bei diesen Operatoren für numerische Vergleiche können auch pure
      Variablennamen -also nicht '$var', sondern 'var'- angegeben werden.
      Die Variablen müssen hierbei aber existieren.

      Die vorgenannten Elementar-Ausdrücke können mittels folgender
      Operatoren verknüpft werden:

      !          Unärer Negations-Operator
      -a         Binärer AND-Operator  (Vorrang vor -o bzw. ||)
      &&         Binärer AND-Operator  (Vorrang vor -o bzw. ||)  [[ ... ]]
      -o         Binärer OR-Operator
      ||         Binärer OR-Operator                     nur bei [[ ... ]]
      (  )       Klammern, um einen bestimmten Vorrang zu erzwingen.

      Achtung, manche Operatoren haben Spezialbedeutung
      für Shell-Programme und müssen ggf. maskiert werden!


 BEISPIELE
      [  $STR = absf -a -n "$DAT" -a %( -s "$DAT" -o "$DAT2" %)  ]
      [[ $STR = absf && -n "$DAT" &&  ( -s "$DAT" || "$DAT2"  ) ]]

      [ $MNT = F -o $MNT = RW -a -z "$2" -o $MNT = R -a -n "$2" ] && echo ...

 NOTA
      Gleichnamige Programme sind unter den verschiedenen UNIX-Systemen
      vorhanden, die dort jedoch oft das Problem haben, Operatoren und
      String-Argumente auseinanderzuhalten, weil die Operatoren ja
      auch Strings sind und die als Strings zu bewertenden Argumente
      einen Operator darstellen können!
      Es wird dort empfohlen, beispielsweise X auf gleiche Weise
      hinzuzufügen:

                X$KVALUE != X-le

      um Eindeutigkeit zu erzwingen.
      Bei diesem Programm ist diese Vorgehensweise nicht notwendig!
      Bei folgendem Ausdruck wird folgendermaßen erkannt:

                test  -o -o -o -a ! -a
                       s  o  s  o o  s

                test  -z

      Führt nicht zu einer Fehlermeldung, sondern zu TRUE,
      weil '-z' schließlich ein nichtleerer String ist.

      Ein weiterer Unterschied ist, daß die Operatoren für
      algebraischen Vergleich bei den Operanden keine anderen Zeichen
      als die oben angegebenen akzeptieren.

      Dieses test-Kommando arbeitet von rechts nach links (!) und
      NICHT mit KO-Logik; alle Teilausdrücke werden bewertet.
      Da nur einfache Tests und Vergleiche ausgeführt werden, ist
      das in der Anwendung jedoch kaum von Bedeutung.
      Wenn eine Reihenfolge erzwungen werden muß, kann man zwei
      oder mehr Kommando-Aufrufe hintereinanderschalten:
           test ... && test ... || ...
      (s. bish(K))

      Grundsätzlich sollten Variablen von "" eingeschlossen sein,
      weil dann bei leerer Variable wenigstens ein Leerargument
      vorhanden ist:   "$VARIABLE"  oder auch  $VARIABLE""
      Gar kein Argument führte zu Mißinterpretation oder Fehlermeldung!


 EXIT-CODE
      0     TRUE        Ausdruck wurde als zutreffend bewertet.
      1     FALSE       Ausdruck wurde als unzutreffend bewertet.
      2     Bei Syntaxfehlern.

 SIEHE AUCH
      bish(K), bish(I,...), regexp®.

 AUTOR
      Dieses Kommando  test  wurde entwickelt von:
      Helmut Schellong, Bad Salzuflen



^

 tee(K)                                                                  tee(K)



 NAME
      tee.exe - Bildet ein T-Stück innerhalb einer Pipeline
      tee       (Intern bish(K))

 SYNTAX
      tee  [ [-a] datei ]
      tee  datei < idatei | kdo
      kdo | tee datei | kdo



 BESCHREIBUNG
      Das Kommando  tee  liest von der Standard-Eingabe und schreibt
      seine Eingabe unverändert zur Standard-Ausgabe und(!) in eine
      angegebene Datei.
      Der Datenstrom in einer Pipeline wird also an der Stelle, wo
      tee platziert wird, angezapft und in eine Datei kopiert.
      Tastatur-Eingabe kann mit ^D oder ^Z beendet werden.

      Bei Angabe einer Datei kann per Option -a ein Anhängen an
      den bisherigen Dateiinhalt gewählt werden (append).
      Wird datei nicht angegeben, wird nur zur Standard-Ausgabe
      geschrieben.



 BEISPIELE
      kdo | tee datei | kdo
         Standard-Verwendung: tee zapft den Datenstrom an und erstellt
         daraus eine Datei.
      tee  datei < idatei t> odatei
         datei ist eine Kopie von idatei, und odatei eine TEXT-Modus-Kopie
         von idatei, mit zusätzlichen CR-Zeichen (\r).


 EXIT-CODE
      0     Kein Fehler.
      1     Wenn keine Datei angegeben wurde.
      2     Bei Fehlern von System-Funktionen.


 SIEHE AUCH
      bish(K)


 AUTOR
      Dieses Kommando  tee  wurde entwickelt von:
      Helmut Schellong, Vlotho
      Copyright © 1995-2017



^

 coder(K)                                                              coder(K)



 NAME
      coder.exe - Kodiert Dateien in Textformen um, und umgekehrt
      coder       (intern bish(K))


 SYNTAX
      coder  -e  [-nv]  [-c code64]  [ quell_vname [ziel_vname]]
      coder  -d  [-sv]  [-c code64]  [[quell_vname] ziel_vname ]
      coder  -e  [-n]   [-c code64]  [ quell_datei [ziel_datei]]
      coder  -d  [-s]   [-c code64]  [[quell_datei] ziel_datei ]
      coder  -ue        [ quell_datei ]  ziel_datei_eintrag  (uuencode)
      coder  -ud [-s]   [ quell_datei ]                      (uudecode)
      coder  -A|-C[#]



 BESCHREIBUNG
      Das Kommando  coder  wandelt jeden beliebigen Dateiinhalt in einen
      Text um und kann solche Kodierungen wieder dekodieren.
      Bei der Umwandlung in eine Textform wird ein reduzierter Zeichensatz
      aus nur 64 verschiedenen Zeichen verwendet - anstatt 256.
      Daher sind solchermaßen entstandene Text-Dateien um etwa 33-35% größer
      als die Quelldateien.
      Die 64 Zeichen werden der aus 95 Zeichen bestehenden Zeichenmenge
      von  ' ' (Space)  bis  '~' (Tilde)  entnommen (ASCII).
      Voreingestellt sind zwei bestimmte Verteilungen:
      uuencode/uudecode (UNIX)  und  eMail-Standard.
      Bei Auswahl 'Standard' können die 64 Zeichen individuell festgelegt
      werden, wodurch ein brauchbarer Verschlüsselungs-Effekt entsteht!

      Der Algorithmus wird 'base64' genannt.
      Der Zeichensatz ist :  "A..Za..z0..9+/"
      Zeichensatz uuencode:  " !.._"
      Das sind in beiden Fällen 64 Zeichen ('..' entspricht 'bis').

      Anhang-Dateien zu eMails sind in den Mail-Ordnern in einer typischen
      Text-Kodierung gespeichert, wie  coder  sie verarbeiten kann.
      coder  kann verwendet werden, falls ein Mail-Programm eine
      bestimmte Kodierung nicht beherrscht oder aus irgendwelchen Gründen
      nicht vornimmt.
      coder  kann auch dabei helfen, Mail-Ordner auf ein anderes
      Mail-Programm zu transferieren.



      coder  berücksichtigt die folgenden Kommandozeilen-Optionen:
      ------------------------------------------------------------
      -e      Es wird kodiert (encode).
      -d      Es wird dekodiert (decode).
              Entweder -e oder aber -d muß angegeben werden.

      -u      Arbeitsweise und Zeichensatz wie bei den Unix-Kommandos
              uuencode bzw. uudecode.

      -s      Ausgabe erfolgt (explizit) auf die Standard-Ausgabe (Handle 1).
              Nur bei -d (decode) verwendbar.

      -n      Ausgabe von Zeilenvorschüben wird unterdrückt.
              Dies kann bei Verschlüsselung sinnvoll sein.
              (Bei -e, nicht bei -u, wirkt nicht bei Bildschirm-Ausgabe)

      -v      Anstelle von Dateinamen werden Variablennamen angegeben.
              Nicht gemeinsam mit -u verwendbar.
              Variableninhalte dürfen bis zu nnn MB groß sein.

      -c      Das Argument nach dieser Option muß eine Zeichenkette
              aus 64 Zeichen sein.
              Damit wird ein selbstgewählter Zeichensatz für den
              Algorithmus angegeben.

      -A      Die Zeichenmenge 'Space bis Tilde' wird angezeigt (außer '=').

      -C#     Es werden 16 Zeichenketten, je 64 Zeichen, ausgegeben, die
              zur Verwendung als 'code64' (Schlüssel) geeignet sind.
              Niemals wird eine Zeichenkette wiederholt.
              Wird eine Dezimalzahl # angegeben, gilt diese Anzahl statt 16.

      Die Optionen (außer -c) dürfen beliebig angeordnet werden.


      Ohne Option -u:
      Bei Funktionswahl 'Standard' werden zwei angegebene Dateien
      als Quelle und Ziel verwendet.
      Bei einer angebenen Datei gibt es einen unterschiedlichen Vorzug,
      je nach Option -e oder -d.
      Und zwar gilt bei -e die Datei als Quelle, bei -d als Ziel;
      weil binäre Daten vorzugsweise in eine Datei gelangen sollten
      und nicht auf den Bildschirm (oder von der Tastatur).
      Ohne Dateiangabe gelten i.d.R. Handle 0/1 als Ein-/Ausgabe,
      man sollte dabei nötigenfalls Umlenkungen (<>|) anwenden.

      Mit Option -u:
      uuencode/uudecode  lesen von der Standard-Eingabe (Handle 0),
      falls  quell_datei  fehlt.
      Ausgabe  uuencode  erfolgt immer auf Handle 1.
      Ausgabe  uudecode  erfolgt nur per -s auf Handle 1,
      andernfalls: siehe unten.

      uuencode  erzeugt einen Text folgendermaßen:
           begin file_mode ziel_datei_eintrag
           ...............................................
           ...............................................
           ...............................................
           ................................
           _
           end
      |
      Der Datei-Eintrag wird von  uudecode  verwendet, wenn Option -s
      nicht angegeben wird.
      uudecode  verlangt diese Form mit Kopf- und Fußzeile.
      Vor der Kopfzeile darf beliebiger Text (ohne Kopfzeile) und
      nach der Fußzeile dürfen beliebige Daten stehen.

      coder  ohne Option -u erzeugt einen Text folgendermaßen:
           ...............................................
           ...............................................
           ...............................................
           ................................

      |
      Leerzeilen werden beim Dekodieren ignoriert.


      Bei Eingabe von der Tastatur (z.B. 'coder -e')
      kann mit <Ctrl+Z> beendet werden.  (Unix: ^D)
      Falls dabei <Enter> vor ^Z eingegeben wird, werden die zwei (Unix: eins)
      Zeichen des Zeilenvorschubs (\r\n) auch kodiert.


      coder als Verschlüsselungs-Programm:
      ------------------------------------
      Per Option -c müssen 64 Zeichen angegeben werden.
      Die 64 Zeichen dürfen und sollen natürlich in völlig beliebiger
      Reihenfolge angegeben werden, also:  Verteilung UND Vertauschung.
      Wichtig ist eine möglichst vielfache VERTAUSCHUNG!
      Jede verschiedene Angabe erzeugt eine verschiedene Kodierung.
      Es können mehrere Stufen hintereinandergeschaltet werden,
      was die Datenmenge jedesmal vergrößert.
      Option -A zeigt die erlaubte Zeichenmenge.
      Kein Zeichen darf doppelt vorkommen.
      Das Zeichen '=' darf nicht vorkommen.

      Beispiele:
      Telefonnummer vierfach kodiert:
           0522284540
           MDUyMjI4NDU0MA==
           TURVeU1qSTRORFUwTUE9PQ==
           VFVSVmVVMXFTVFJPUkZVd1RVRTlQUT09
           VkZWU1ZtVlZNWEZUVkZKUFVrWlZkMVJWUlRsUVVUMDk=
      Dies wurde allerdings mit -immer dem gleichen- eingebauten
      Zeichensatz (mit -n) gemacht!
           0522284540
           #b5A#}"D1b5s#w==
           zLz{*%@oz-*,jk4bzWcoi*==
           va\;vZ-(+C~;}.-^Q2^UR$y|R@~yA]U~
           Q.OH8($"hMfK>(&!<M&Vp,g%p,4M#@,n62:/76OQ4p&=
           815n12<4}*}4;^VPn%<o6;9(}LV.P_|L|*.\;1(AP_RX/v4a(QVn8;:.}v\=
      Bei vorstehender Kodierung wurden nacheinander fünf verschiedene
      Schlüssel von Option -C her verwendet.
           11111111111111111111111
           5+I}5+I}5+I}5+I}5+I}5+I}5+I}5+I=
           [hu0U+b-h1tCBtL`[hu0U+b-h1tCBtL`[hu0U+b-h+t=
           S|WC5Fb-k.CT51\(fn\5kFuTV+;vB|xuA(Ftft0t+@;EAgb~vhu.^SJ-V(t=
      Vorstehend ist erkennbar, daß trotz Verwendung des immer gleichen
      Schlüssels, die Gleichartigkeit durch die dritte Stufe beseitigt ist.
           a                             a
           P^==                          `m==
           ?t<TZb==                      bGv`q*==
           rsvSZV*3r\p=                  6d826)+H~Lu=
           ntUGJv3"%5U8eEVi              9A(V4tw+aLgeW6Oy
           *fP+Pb}0c>SD{+kA#k+Q~\==      :e@D0;E8qJuBC&q>0W~.FP==
           a                             a
           i~==                          6A==
           78I}%n==                      4X|+U-==
           Iej%?G>}k|o=                  ]Wn3t+*p^@`=
           /2>]n3e.x_HBrj%e              (P[?H_oLJ#I*o\~$
           E:46xCf:7(%fx$"S!cwe7V==      YW#p:~P@p~qYy~3Bp-qRb.==
      Vier Verschlüsselungen von 'a' mit jeweils verschiedenen Schlüsseln.
      Das Anhängen von '=' wird vorgenommen, damit die Länge der kodierten
      Daten ohne Rest durch 4 teilbar ist.

      Eine Ausgabe per Option -C:
         w$>b!QBG"gje#16%VTRJ5-pq[K\O;r_H4o]}7@NMyl:{nfh~(/AYsvPCD,.x)m&t
         Z]l+B(OYzt&1s@vi*K%er4M>j.R~cV`H?uqk-g)Dd5!JU}y[T,"bQ{LW_m69aoNf
         8Tn:/DC0YEA}zOFS+c.*B3_|R9Q&#XvGkI>]a(2$-yfW^pVbN\Z1U?@L6t;eq~,u
         D:s~gO_@R#1hiX83>\Mb64rp5$"GHQ7<fBUN2,.}|W9KxVm?E*%TSFy(&wc!n`/P
         AN*2{k_)6}BP/([nC:1;8m^]"V?,|U`O<Z%vjLoe4q+Fc-#a.9HQ\lX&R5@GEiIu
         eI0bjQ4rX,&%w^pZq)cW]+9u*D:56y@Gls[Jxv$>"_B7k?#m~Y!{;`PK1LAS}T-F
         L.Y}5?/Vt[EJq2#a"4UOwc\s%0v9x3pI~^PhkTeGRCAzyjBM<>@*:1HbD`d8)n!K
         <vIWYtxBasc*Pzuw>_-eA)o9l~4y!nFE6$(.DS\mph"{1VqLM]J2}+Zr`[GKikb;
         XP)S},83/l^inAs2O%+;{EBqygL\[7jFeh$Qp"M|]9<U@w*IrbC>61z!?~#uVt&a
         0[E5]HC92uYjB<s&RZlv6Uzk\/ct*,)g-4M`xya^InQd1~p+7}e$T8A#hr%3iD:X
         }tV/k1fH_w,S7Eu@U4o#ih\)Tp2gI"B*ARynMZ{Cje[.c?zs>30Fl`^WQd5ND$aL
         D;](IF@gx0B^5[iQf\h+bvS1k:AEdV{UJW.paLrnTN$-lu6s~}H/tC|q,y4)j`2M
         vcW/m^>*Llk7\JU.!syN|C%1Ep[VP#,qaz`ifA{do3XgB&$I)n69-Q0H_tu;+F]5
         ]Lxz`3t0~jN<XlDe!4K,JvU?IG%W{pr&:ZH86V5@>1kTSnPds/2Bb(;"C#.oAiwQ
         1V\&ERnU.,@~KM#(i3pz|4y5o_xlT%[jPYb/w9ACJXH<?h}vL^6De8;r)t!c2kWB
         [+Y9Z7zE`$T]m^eru%1O&#CnVliqN(g6WP!oUG:>sh?*MSX}DaA~8cy0_\KJ<j54
      Leerzeichen, = und ' werden ausgefiltert.
      Es wird niemals eine Zeichenkette wiederholt werden, da diese
      Schlüssel durch den 'Spritz'-Random-Algorithmus generiert werden.

      Diese Kodierung mit dem bekannten Algorithmus base64 ist natürlich
      ohne Angabe von '-c schlüssel64' keine wirksame Verschlüsselung!
      Wenn sich in der Quelle hinten ein Zeichen ändert, ändert sich meistens
      auch nur ein Zeichen hinten bei der verschlüsselten Ausgabe.
      Aber durch Hintereinanderschaltung mit jeweils verschiedenen Schlüsseln
      wird es doch eine wirksame Verschlüsselung:
      o  Außer den abgesprochenen Anwendern kennt niemand die Schlüssel.
      o  Niemand sonst kennt die Quelle und deren Länge.
      o  Niemand sonst kennt die Anzahl der Verschlüsselungsschritte.
      o  Bis auf die letzte Rückwandlung ergibt sich stets unlesbarer Text.
      o  Eine Dekodierung mit anderen als den originalen Schlüsseln in
         der richtigen Reihenfolge führt oft zum Abbruch des 'coder', weil
         oft illegale Werte außerhalb des korrekten Zeichensatzes entstehen.
         Der Schlüssel paßt dann nicht zum zu dekodierenden Text.
         Der 'coder' kann also zum Codebrechen nicht benutzt werden.
      o  Falls ein Schlüssel gefunden wurde, der zum Text paßt, dann ist
         die richtige Reihenfolge der Zeichen noch gar nicht bekannt.
      o  Falls tatsächlich ein verwendeter Schlüssel herausgefunden wird, so
         ist es nicht erkennbar, daß dies so ist.
      Mit einem Kommunikationspartner können auch verschlüsselte Schlüssel
      ausgetauscht werden. Nur ganz zu Anfang muß eine sichere Übergabe
      stattfinden.


 WARNUNGEN
      Bei Angabe von Code-Zeichen per Option -c sollte kein Zeichen
      (später intern) doppelt vorhanden sein,
      es kann sonst nicht eindeutig zurück-dekodiert werden!
      In einem solchen Fall erfolgt ein Warnhinweis.

      Bei Kodierung/Dekodierung muß natürlich der gleiche Schlüssel
      verwendet werden.

 HINWEISE
    coder als Verschlüsselungs-Programm:
      Der  coder  sollte keinesfalls als einzige Stufe verschlüsseln!
      Mindestens eine starke Verschlüsselung oder zwei coder-Stufen
      sollten unter einer abschließenden coder-Stufe liegen.
      Der stärkste Verschlüsselungseffekt entsteht grundsätzlich durch die
      Hintereinanderschaltung von unterschiedlichen Algorithmen.
      Das bildet eine Barriere und vernebelt BruteForce-Versuche.

      Der offizielle Zeichensatz für 'base64' ist:
      ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/
      Index 0 bis 63.
      Da lag es nahe, eigene als Kodierungs-Schlüssel zu verwenden:
         w='D;](IF@gx0B^5[iQf\h+bvS1k:AEdV{UJW.paLrnTN$-lu6s~}H/tC|q,y4)j`2M'
         conv -S w; echo "$w"     #sortieren
         $()+,-./012456:;@ABCDEFHIJLMNQSTUVW[\]^`abdfghijklnpqrstuvxy{|}~
      Durch hintereinander geschaltete solche Verschlüsselungen entsteht eine
      sichere, praktisch nicht brechbare Verschlüsselung.

      .*.***..**.*.***.*.****..***.*.******.*.**.*.**.**.*.***.*.*
      Der interne Zeichensatz stellt sich wie vorstehend dar.
      Er wird vom Schlüssel generiert und ist dessen Abbild.
      Falls beim Dekodieren wegen eines unpassenden Schlüssels ein
      Zeichen '.' getroffen wird, beendet das Kommando wegen Fehlers.
      Andernfalls wird meist ein falscher '*' getroffen, wodurch das
      Kommando stumm unpassend dekodiert.
      Dieser unpassende Inhalt paßt nun nicht mehr zu einem korrekten
      nächsten Schlüssel!

      1 -------------------------T----L---------------------------------
      2 ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/
      3 -------------------------L----T---------------------------------
      4 ABCDEFGHIJKLMNOPQRSTUVWXYZabcdyg§hijklmnopqrstuvwxyf0123456789+/
                                      ^^^                  ^
      Zeile 2 wurde nach Verschlüsselung mit 1 mit einem gefälschten
      Schlüssel (3) entschlüsselt. Das Resultat ist Zeile 4.
      Das Resultat enthält insgesamt vier verschobene und neue Zeichen.
      Im Schlüssel wurden nur zwei Zeichen untereinander getauscht.
      Also nur ein Swap! Zeichen im Wert verändern führte in jedem Fall
      zu einem Abbruch des Kommandos wegen Fehler.
      Das neue Zeichen § führt als Dateiinhalt ebenfalls zum Abbruch.
      Es ist zu beachten, daß es sich nicht nur um ein Zeichen-Mapping
      handelt, sondern auch um eine Umsetzung von vier Bit-Feldern
      mit je 6 Bit in drei Byte mit je 8 Bit - beides mit 24 Bit.

      64 Zeichen aus einer Gesamtmenge von 95 Zeichen.
      Kombinationslehre: 'n über k' = (n)(k)  ;  x! = 'Fakultät von x'
      (95)(64) = 9,9e24 = 9900000000000000000000000
      So oft können also 64 Zeichen verschieden in 95 verteilt werden.
      Verteilung OHNE Rücksicht auf die Reihenfolge (mit Vertauschungen):
      [(95)(64)]*64! = 1,256e114  ;  64! = 1,27e89
      Durch Hintereinanderschaltung von Kodierungen können (maximal)
      die Exponenten pro Stufe erhöht (verdoppelt) werden.

      Obwohl die Verschlüsselungs-Effektivität gering ist, im Vergleich
      zu z.B. einer kryptologischen Stromverschlüsselung wie Rabbit, muß doch
      der angegebene Schlüssel korrekt sein, um erfolgreich zu entschlüsseln!
      Es gibt hier zunächst 95^64 = 3,75e126 verschiedene Schlüssel.
      Da kein Zeichen doppelt oder häufiger vorkommen darf, gilt der Wert
      von oben: 1,256e114.
      Bei drei Verschlüsselungen hintereinander mit drei verschiedenen
      Schlüsseln sind es 1,256e114^3 = 1,98e342 verschiedene Gesamt-Schlüssel.
      Bei der Annahme von 30 ns Zeitbedarf pro Schlüsselwort-Versuch dauerte
      eine BruteForce-Aktion 1,9e327 Jahre, falls der richtige Schlüssel
      erst ganz zum Schluß gefunden würde.
      
      Die Verschlüsselung von  coder  ist natürlich ein Nebeneffekt!
      Zum besseren Umgang kann man SET und/oder DOSKEY zu Hilfe nehmen,
      noch besser ist ein 'richtiges' Shell-Programm, wie 'bish.exe'.

    Ein Test-Skript:
      set -f
      array 0 15 code $(coder -C16)
      z0=a
      for n from 0 by 1 to 15 repeat
      do
         array C=code n
         zn=z$((n+1))
         coder -env -c "$C" z$n $zn
         print -r "$n: ${{zn}}"
      done
      z16="${{zn}}"
      for n from 15 by -1 to 0 repeat
      do
         array C=code n
         zn=z$((n+1))
         coder -dnv -c "$C" $zn z$n
         yn=z$n
         print -r "$n: ${{yn}}"
      done


 DIAGNOSE
      Fehlermeldungen zur Standard-Fehlerausgabe.

 EXIT-CODE
      0     Kein Fehler
      1     Fehlerhafte Argumentliste
      2     Dateiöffnen fehlgeschlagen
      3     Fehler beim Dateilesen
      4     Falsche/Fehlposititionierte Zeichen in Code-Datei
     >0     Sonstige Fehler


 SIEHE AUCH
      uuencode(UNIX), uudecode(UNIX), mpack(), munpack(), bish(K).


 AUTOR
      Das Kommando  coder  wurde entwickelt von:
      Helmut Schellong, Vlotho
      Copyright © 1998-2016



^

 man(K)                                                                  man(K)



 NAME
      man.exe - Zeigt Beschreibungen (Manual Pages)

 SYNTAX
      man  [rubrikbuchstabe] titel



 BESCHREIBUNG
      Das Kommando  man  sucht aus einer Ansammlung von Dateien
      eine zu den Kommandozeilen-Argumenten bzw. zum Titel-Argument
      passende heraus und präsentiert deren Inhalt mittels anderer
      Hilfskommandos.

      Die Dateinamen haben folgendes Format:

                <titel>.<mn><rubrikbuchstabe>
                <titel>.<me><rubrikbuchstabe>   (english)

      Folgende Rubrikbuchstaben (Großbuchstaben!) sind derzeit zugeordnet:

                A     Anfangs zu lesende Übersichten
                B     Beispielhaftes
                D     Datenblatt
                I     Informationen
                K     Kommando-Beschreibungen
                L     Limits/Leistungswerte
                R     Referenz
                S     Kurzbeschreibungen
                T     Tutorial
                V     Vergleiche/Leistungsmerkmale

      Gültig sind alle Buchstaben von 'A' bis 'Z'.


      Die Dateien sind komprimiert, weshalb 'man' einen Entpacker
      einschaltet. Das zweite Hilfskommando ist ein wählbares
      Pager-Programm wie beispielsweise pg oder more.
      Dateien, die keinen speziellen Datei-Kopf für den Entpacker
      besitzen, werden von diesem unverändert durchgeschleust.

      Rubrikbuchstaben werden verarbeitet, weil damit trotz gleicher
      Titel eine Unterscheidung getroffen werden kann.
      Wenn kein Rubrikbuchstabe angegeben wird, durchsucht 'man'
      alle Rubriken, sonst nur die angegebene.
      Nur ein gültiger Rubrikbuchstabe wird als solcher interpretiert.
      Andernfalls wird nach ihm ein Titel gesucht.
      Ein zweites Argument ist nur erlaubt, wenn das erste eine
      gültige Rubrik ist. In diesem Fall muß ein zweites Argument
      als Titel angegeben werden.

      man berücksichtigt folgende Umgebungsvariablen (Environment):
      MANTEMP, TEMP, TMP, TEMPDIR und TMPDIR
        in der angegebenen Reihenfolge, zur Angabe
        eines Verzeichnisses für temporäre Dateien.
        Standardverzeichnis ist das aktuelle Verzeichnis.
      MANFILES
        Zur Angabe eines Verzeichnisses für die gepackten man-Dateien.
        Standardverzeichnis ist das aktuelle Verzeichnis.
      MANRUBRIK
        Um die Suchreihenfolge festzulegen:  MANRUBRIK=KIABCDE...
        Voreingestellt ist  ABCDE...XYZ .
      MANPAGER, PAGER
        Zur Angabe des Namens eines Pager-Programms.
        Optionsargumente können zusätzlich angegeben werden.
        Standardaufruf ist  `pg -n' .
        Wird das Umlenkungszeichen `<' angegeben, wird dem ausgewählten
        Pager-Programm kein Dateiname als Argument übergeben, sondern
        die (temporäre) Datei wird geöffnet und mit der Standardeingabe
        verknüpft.
        Um DOS-more zu benutzen, muß eine dieser Env-Variablen
        auf  `"more<"'  gesetzt werden, weil dieses Kommando nur per
        Umlenkung arbeitet und nur von der Standardeingabe lesen kann.
      MANAUTOR
        Um die Autoren-Meldung zu unterdrücken:
        MANAUTOR=H.Schellong,Vlotho
      MANPROGRAM
        Um die Freeware-Meldung zu unterdrücken:
        MANPROGRAM=Freeware_nur_fuer_nichtgewerbliche_Verwendung
        (MANAUTOR muß hierfür auch gesetzt sein.)


 HINWEISE
      Falls MANRUBRIK auf einen bestimmten Inhalt gesetzt ist, sucht
      das man-Kommando ausschließlich nach den hier angegebenen Rubriken.
      Eine beim Kommandoaufruf angegebene Rubrik hat stets Vorrang.

      Bei Beendigung des Programms erfolgen gegebenenfalls Hinweise
      auf gleichnamige Manual-Dateien anderer Rubriken.


 BEISPIELE
      man man
      man pg
      man R regexp > datei

 EXIT-CODE
      0     Kein Fehler aufgetreten.
      1     Allgemeiner Fehler (Argumente, falsche Datei, etc.)
      2     Wenn eine Systemfunktion einen Fehler meldete.

 AUTOR
      Dieses Programm  man  wurde entwickelt von:
      Helmut Schellong, Bad Salzuflen



^

 xregexp®                                                          xregexp®



 NAME
      xregexp - Definition der Schreibweise sogenannter
                Regulärer Ausdrücke (regular expressions)



 BESCHREIBUNG
      Ein Regulärer Ausdruck ist ein Mechanismus zur Feststellung der
      Position einer ganz bestimmten Zeichenfolge oder um ein solches
      Muster gezielt zu manipulieren.
      Dieser Mechanismus wird von vielen Hilfsprogrammen unterstützt.
      Zeichenmustervergleich wird von Shell- und anderen Programmen zur
      Verfügung gestellt, hauptsächlich zur Dateinamen-Expansion.

      Diese Beschreibung xregexp® umfaßt Reguläre Ausdrücke in einer
      Ausprägung, die den Gipfelpunkt in diesem Bereich darstellt,
      nämlich XRE, im Unterschied zu BRE und ERE, die von IEEE/POSIX
      beschrieben werden.
           Wildcards(DOS), Wildcards(UNIX),   BRE, ERE,   XRE
      sind die bekannten Mechanismen mit aufsteigender Komplexität.

      Nachfolgend eine kleine Übersicht von speziellen Zeichen und
      Zeichenfolgen, zur Einordnung der Komplexität:
      DOS      *  ?
      UNIX     *  ?  [! ]
      BRE      . [^ ]  * \{ \}  \( \)  \1  ^ $
      ERE      . [^ ]  * + ? { }  ( )  |  ^ $
      XRE      sprengt hier den Rahmen, siehe unten
               (Etwa 20-fach komplexer als ERE)

      Es beginnt einfachst mit dem Zeichen *, das für beliebig viele
      beliebige Zeichen steht, bei der Dateinamen-Expansion.
      Ab den BRE repräsentiert * keine Zeichen, sondern ist nur noch
      ein Element, welches eine Anzahl angibt.
      Es erfolgt eine Trennung: Die Zeichenfolge .* entspricht nun *,
      wobei . für ein beliebiges Zeichen und * für eine Anzahl
      zwischen Null und Unendlich steht.

      Nachfolgend werden die XRE beschrieben.
      Der 'Reguläre Ausdruck' wird zu RA gekürzt.
      Die zu untersuchenden Daten, auf die der RA angewendet wird,
      werden als DATEN bezeichnet.

      Sogenannte 'Regex Engines' sind:
        JGsoft  .NET  Java  Perl  PCRE PCRE2  PHP  Delphi  R
        JavaScript VBScript  XRegExp  Python  Ruby  Tcl
        'POSIX BRE/ERE IEEE Std 1003.1' 'GNU BRE/ERE'  Oracle  XML  XPath
      Webseite:  http://www.regular-expressions.info/tutorial.html
      Einige enthalten keine eigenständige Regex-Software, sondern verwenden
      Funktions-Bibliotheken, beispielsweise die Bibliothek PCRE.

      Die Syntax der bish-XRE folgt der mehrheitlichen oder optimalsten
      Syntax der vorstehend genannten RE-Maschinen.
      Die RE-Maschinen zeigen ein großes Durcheinander hinsichtlich
      der Syntax, besonders bei der Substitutions-Syntax.
      Bei den bish-XRE wurde darauf geachtet, zumindest homogene Linien
      zu verfolgen.



 BESONDERHEITEN

    Eindeutigkeit und Sicherheit
      Es wurden automatisch wechselnde Spezialbedeutungen weitgehend vermieden.
      Das Maskierzeichen ist nur innerhalb von definierten Zeichenfolgen
      erlaubt.
      Es herrscht weitestgehend Striktheit und Eindeutigkeit.
      Für die XRE sind mehr als 50 Fehlermeldungen implementiert.

    Rein Binäres Konzept
      Ein RA darf direkt Zeichen (Bytes) mit den Werten 1 bis 255 enthalten.
      Indirekt können alle Werte 0 bis 255 durch Umwandlung in den kompilierten
      RA eingefügt werden.
      Die DATEN können in einer bish-Variablen enthalten sein, die Millionen
      von Bytes mit allen Werten von 0 bis 255 enthalten kann.
      Es gibt kein Zeilenende bei der bish-XRE, sondern nur einen
      Pufferbeginn und ein Pufferende hinsichtlich der DATEN, die auch nicht
      null-terminiert sind.
      Die bish(K) bietet einen sehr guten Rahmen für den Umgang mit RA.
      Deren interne Kommandos grep(K) und expr(K) verwenden BRE und XRE.
      Die Programmierbarkeit der bish potenziert noch die Leistung der XRE.

      Es können binäre Datenstrukturen bis zu einer Größe von mehreren hundert
      Millionen Bytes untersucht und Ersetzungen darin vorgenommen werden.
      Solche Strukturen können auch generiert werden.

    Sophisticated
      Die RA der bish-XRE können in beiden Richtungen abgearbeitet werden.
      Das hat beträchtliche Vorteile bei 'Lookbehind'-Konstruktionen.
      Von den 22 oben genannten RE-Maschinen besitzen nur JGsoft und .NET
      diese Fähigkeit. Nun gesellt sich die bish-XRE hinzu.

    Performance
      Die bish(K) ist das schnellste Shell-Programm.
      Ebenso werden deren XRE-RA sehr schnell verarbeitet.
      DATEN                                   RA
      01234567890123456789abcggdefgdedeffkz   abc(g+(de){1,2}f+){0,2}k
                          abcggdefgdedeffkz   abc(g+(de){1,2}f+){0,2}k
      Der vorstehende RA benötigt 310/270 ns auf einem Core2 Duo 3333 (2007).
      Matches:  abc(ggdefg(dede)ff)k

    Konfigurierbarkeit
      Siehe nachfolgend die vollkommene Einstellbarkeit aller Zeichen
      mit Spezialbedeutung.


 SAMMLUNG SPEZIELLER ZEICHENFOLGEN

      % %% \ \\ . [ * + ? { ( ) | < > ^ $
      a* a+ a? a{m,n}  a*? a+? a?? a{m,n}?  a*+ a++ a?+ a{m,n}+
      a{m,} a{m}  a{0..4294967295,0..4294967295}  a:= a . ( ) [ ]
      # \Q \E \p{Lx} (37) \P{Lx} (37)  \Z \z  \,
      \g<name> \g'name' \g{name} \k<name> \k'name' \k{name}
      \g<zahl> \g'zahl' \g{zahl} \k<zahl> \k'zahl' \k{zahl}
      \g<-zahl> \g'-zahl' \g{-zahl} \k<+zahl> \k'+zahl' \k{+zahl}
      \K  \G  \b \B  \0 \1 \2 \3 \4 \5 \6 \7 \8 \9
      \cA..\cZ  \ca..\cz  \c0..\c9  \e \t \r \n \v \f
      \d{zahl}  \o{zahl}  \x{zahl}  \u{zahl}
      \s \d \x \o \w \h \a \l \u       82 vordef. Z.k.
      \S \D \X \O \W \H \A \L \U \N
      [:alnum:] [:alpha:] [:blank:] [:cntrl:] [:digit:]
      [:graph:] [:lower:] [:print:] [:punct:] [:space:]
      [:upper:] [:xdigit:] [:ascii:] [:word:]
      [a-z-[aeiou]]  [^a-z-[a-z-[^xx]]]  [0-9&&[0-6&&[4-9]]]
      (...)  (?<name>...)  (?:...)  (?|...)  (?>...)
      (?=...)  (?!...)  (?<=...)  (?<!...)  (?#...)
      (?imnsxb-inmsxb)  (?^inmsxb)  (?imn:...)
      (?R)  (?0)  (?1)  (?-1)  (?+1)  (?&name)  (?(DEFINE)(...))
      (?(name)then|else)  (?(zahl)then)  (?(expr)then|else)
      (?<name1-name2>expr)  (?<-name2>expr)
      $nummer  ${name}  ${*abc*123}  ${$name}
      $$ $& $` $' $_  $U $L $E $I $F  $t $r $n
      -------------------------------------------------------------------
      Vorstehend eine sehr kompakte Zusammenfassung, die bei vorhandenen
      Kenntnissen einen sehr schnellen Überblick zu den implementierten
      Merkmalen erlaubt.
      Es ist erkennbar, daß dies die hochstehendste Kategorie
      Regulärer Ausdrücke ist, mit großem Abstand sogar zu den ERE.


 ZEICHEN MIT SPEZIALBEDEUTUNG

    Generelles Maskierzeichen
      Prozentzeichen  %
      Backslash       \
      Das Maskierzeichen ist wählbar durch die bish-Option '-B'
      und das bish-Kommando 'set -B' bzw. 'set +B'.
      Voreingestellt ist '%'.
      Angabe von '-B' wählt '\' und '+B' selektiert '%'.

      Das Maskierzeichen kann außerdem im RA selbst mittels
      Optionen-Syntax (?b) gewählt werden.

      Ein einem Spezialzeichen vorangestelltes Maskierzeichen hebt die
      Spezialbedeutung des Spezialzeichens auf und macht es zu einem
      gewöhnlichen Zeichen. (Falls nicht gegensätzlich definiert.)
      Das Maskierzeichen 'verbraucht' sich dadurch; eine Folge \* wird
      zu einem gewöhnlichen Zeichen *.
      Es ist ein Fehler, wenn das nachfolgende \Zeichen keine
      Spezialbedeutung hat.
      Das Maskierzeichen selbst wird durch '\\' oder '%%' zu einem
      gewöhnlichen Zeichen \ oder %.

      Die Maske % ist unter DOS/Windows und UNIX unproblematisch.
      Die Maske \ ist unter DOS/Windows problematisch, allerdings
      optisch vorteilhafter.

    Spezialzeichen
      .  [  *  +  ?  {  (  )  |  <  >  ^  $
      Viele der vorstehenden Zeichen bilden den Beginn einer definierten
      speziellen Zeichenfolge. Nachfolgende Zeichen, die dadurch
      Spezialbedeutung erhalten oder bereits haben, sind oft optional.

      Für jedes der Spezialzeichen ist konfigurierbar, ob es ohne oder mit
      dem Maskierzeichen (% \) Spezialbedeutung haben soll:
      set -XRE='<>'      < und > sollen als \< und \> speziell sein.
      set -XRE=          kein Zeichen soll mit \ speziell sein;
      set -XRE=          alle Zeichen sollen ohne \ speziell sein.
      set -XRE           zeigt alle Zeichen, mit oder ohne Maskierzeichen.
      Voreingestellt ist:  $()*+.\<\>?[^{|
      Für alle hinter XRE= angegebenen Zeichen aus der oben definierten Menge
      wird definiert, daß sie nur gemeinsam mit einem vorangestellten
      Maskierzeichen speziell sind.
      Für alle nicht angegebenen Zeichen aus der oben definierten Menge
      wird definiert, daß sie nur ohne vorangestelltes Maskierzeichen
      speziell sind.


 BEDEUTUNGSGRUPPEN

    Leere Zeichenketten
      Ein leerer RA '' paßt zu jeglichen DATEN, logischerweise auch
      zu leeren DATEN ''.
      ''  '^$'  '^'  '$'  passen jeweils zu leeren DATEN ''.

    Gewöhnliche Zeichen
      Jedes einzelne Zeichen, das keine Spezialbedeutung hat, ist ein
      gewöhnliches Zeichen, sofern keine spezielle Bedeutung durch
      den Kontext entsteht.
      Ein gewöhnliches Zeichen ist bereits ein RA.
      Ein Spezialzeichen wird zu einem gewöhnlichen Zeichen durch
      Voranstellen des Maskierzeichens.
      Ein Spezialzeichen, das nur durch Voranstellen des Maskierzeichens
      speziell ist, wird durch Weglassen des Maskierzeichens zu einem
      gewöhnlichen Zeichen.
      Die Sequenzen \r \n (beispielsweise) repräsentieren jeweils ein
      gewöhnliches Zeichen. Ebenso die Zeichenklasse \w.

    Spezialzeichen
      Ein Spezialzeichen kann einzeln einen RA bilden.
      Einige Spezialzeichen sind ohne bestimmte Zeichenfolgen davor
      oder dahinter ein Fehler.
      DATEN  RA
      a      \<   paßt
      4      \<   paßt nicht
      4      *    ist ein Fehler
      4      \*   paßt nicht

    Spezielle Zeichenfolgen
      In einer vorstehenden Sektion sind viele Darstellungen enthalten.
      Ein großer Anteil davon wird durch das Maskierzeichen eingeleitet
      und von einem unmittelbar folgenden Buchstaben beendet.
      Ein oder mehr Zeichen hinter dem Maskierzeichen sind im Regelfall
      einzeln und ohne das führende Maskierzeichen gewöhnliche Zeichen.
      Im ersten Schritt bildet das Maskierzeichen mit einem direkt
      folgenden Zeichen eine Folge mit einer ganz bestimmten Bedeutung.
      Danach können beispielsweise zwanzig weitere Zeichen folgen, die
      wiederum in diesem Kontext ganz bestimmte Bedeutungen aufweisen.
      Weitere spezielle Zeichenfolgen werden nicht durch das Maskierzeichen
      begonnen, sondern durch ein anderes Spezialzeichen, nämlich durch
      die eigentlichen RA-Symbole.

    Zeichenrepräsentanten
      Zeichen und andere Syntaxkonstruktionen, die im RA für ein Zeichen
      aus den DATEN stehen, sind:
      a           Gewöhnliches Zeichen (s.o.)
      .           Paßt zu jedem Zeichen (Byte) in den DATEN
      [ ]         Zeichenklasse (auch \d \w ...)
      Es gibt tatsächlich nur diese drei Repräsentanten.
      Der Punkt paßt im SingleLine-Modus zu jedem Zeichen.
      Es sind sehr viele vordefinierte Zeichenklassen vorhanden.

    Gruppen
      (   )       Standard-Gruppe (speichernd/capturing)
      (?: )       Gruppe, explizit nicht speichernd
      Innerhalb der BRE ist ( ) keine Gruppe, sondern die beiden Zeichen
      sind lediglich Positionsspeicher-Symbole.
      Letzteres gilt bei den XRE ebenfalls, jedoch können allen oder einigen
      Elementen zwischen ( ) bestimmte Eigenschaften zugewiesen werden.
      Insbesondere sind Gruppen quantifizierbar.
      Innerhalb der Gruppen können beliebig Zeichenrepräsentanten
      und andere Syntaxelemente angeordnet werden.

    Quantifizierer
      SYNTAX      MIN    MAX            BEISPIEL       HINWEIS
      ohne        1      1              a              possessiv
      *           0      unendlich      a*
      +           1      unendlich      .+
      ?           0      1              [ ]?
      {m,n}       m      n              a{2,8}
      {m,}        m      unendlich      ( ){6,}
      {m}         m      m              ( ){5}         possessiv
      {m,m}       m      m              ( ){5,5}       possessiv
      m,n = 0 .. 4294967295 ; unendlich = 4294967295

      Quantifizierer geben an, wie viele Zeichen oder Zeichengruppen aus den
      DATEN jeweils mindestens und maximal repräsentiert werden sollen.
      Bei Zeichen gilt N bzw. N*1.
      Bei Gruppen gilt nicht N*L, sondern L1+L2+L3+..+Ln.
      Jede Wiederholung einer Gruppe kann folglich eine unterschiedliche
      Anzahl von Zeichen in den DATEN überspannen!
      Die possessiv-Kennzeichnung hier zeigt implizite Possessivität.

    Wiederholungsverhalten (Qualifizierung)
      SYNTAX      BEGRIFF    ERKLÄRUNG                          BEISPIEL
                  greedy     (gefräßig) (ohne Syntax)           a+
      ?           lazy       (faul)                             a*?
      +           possessive (possessiv/besitzbeanspruchend)    a{4,6}+

      Das verhaltenssteuernde Zeichen wird jeweils hinter dem Quantifizierer
      angegeben. Diese Verhaltensweisen haben viel mit der grundlegenden
      Arbeitsweise von RA zu tun:  Von links nach rechts - und dabei gefräßig.
      Das Verhalten 'greedy' liegt auch in BRE und ERE vor.
      'greedy' und 'lazy' sind Geschwister, während 'possessive' davon
      abgesetzt ist.
      Eine RA-Einheit (z.B. a+) versucht 'greedy', so viele Zeichen aus
      den DATEN zu überspannen, wie möglich. Danach gibt sie im Interesse
      der nachfolgenden Einheit so viele Zeichen an diese ab, bis sie und
      auch die nachfolgende Einheit passen, sofern das im gesamten Bereich
      der abgebbaren Zeichen möglich ist.
      Dies kann als ziemlich aufwendiges Justieren bezeichnet werden.

      Eine 'lazy'-Einheit (z.B. a+?) gibt zu Anfang alle ihre abgebbaren
      Zeichen ab, und justiert nachfolgend aufsteigend, bis beide passen, im
      Rahmen der abgebbaren Zeichen.
      RA               DATEN            MATCH
      (b+)(b+)         abbbbc           (bbb)(b)
      (b+?)(b+)        abbbbc           (b)(bbb)
      2(nd)?           a2ndc            2nd
      2(nd)??          a2ndc            2
      <.+>             <b>bold</b>      <b>bold</b>
      <.+?>            <b>bold</b>      <b>
      \b.*[\d]{4}\b    1995 2015        1995 2015
      \b.*?[\d]{4}\b   1995 2015        1995

      Eine 'possessive'-Einheit (z.B. a++) hingegen justiert überhaupt nicht!
      Sie gibt nichts mehr von ihrem Passenden ab. Das erhöht die
      Verarbeitungsgeschwindigkeit.

      MIN,MAX: 1,1  m,m  sind implizit possessiv (siehe oben).
      Verwendung von 'lazy' und 'possessive' kann dazu führen, daß ein RA
      im Unterschied zu 'greedy' nun paßt oder aber nicht mehr paßt, oder
      korrekt paßt.

    Anker
      SYNTAX    ERKLÄRUNG
      ^         'RA  'DATEN     vorne verkoppelt
      $          RA'  DATEN'    hinten verkoppelt
      \Z         RA'  DATEN'    hinten verkoppelt
      \z         RA'  DATEN'    hinten verkoppelt
      ^  $      'RA' 'DATEN'    vorne und hinten verkoppelt

      Ein Anker bewirkt eine feste Verknüpfung der Anfangspunkte oder der
      Endpunkte von RA und DATEN.
      Der Anfang der DATEN muß zum Anfang des RA passen, bei Vorneverknüpfung,
      andernfalls passen die DATEN nicht zum RA.
      Vorneverknüpfung steigert die Verarbeitungsgeschwindigkeit:
      Normalerweise werden die DATEN aufsteigend zeichenweise abgefragt, dem
      RA jeweils zur Prüfung vorgelegt. Das entfällt bei Vorneverknüpfung.
      Es sollten die Anker  ^ $  verwendet werden.

      Die weiteren Anker geben im Multiline-Modus ein anderes Verhalten.
      Dieser Modus ist jedoch nicht implementiert.
      Die Sequenz \A ist bei den XRE kein Anker, sondern eine Zeichenklasse.
      Die Anker sollen vorne beziehungsweise hinten positioniert werden.
      Kommentare können davor und im x-Modus auch dahinter stehen.
      Unter anderem deshalb haben die Anker nicht nur ganz am Anfang bzw.
      ganz am Ende Spezialbedeutung, sondern überall.

      '(?#co)(?x)    ^a\,b $  #XC '    --    entspricht '^ab$'
      Anker können wie vorstehend positioniert werden.
      Kommentar, Optionsetzen und x-Modus ermöglichen hier eine Position, die
      normalerweise nicht gestattet ist.
      
      
 ZEICHENKLASSEN

    Grundlegende Syntax
      [abc]             paßt zu a b c
      [^abc]            paßt zu allen Zeichen, die nicht a b c sind
      [a-z]             paßt zu a bis z, einschließlich
      [A-Za-z_0-9]      paßt zu allen in Wörtern üblichen Zeichen
      []abc]            paßt zu ] a b c
      []^abc]           paßt zu ] a b c ^
      [abc-]  [-abc]    paßt zu - a b c
      [a-e-z]           paßt zu - a b c d e z
      []-abc]           paßt zu ] a b c -
      [-a-c]            paßt zu - a b c
      Die vorstehende Syntax ist üblich ab den BRE.
      Zwei Zeichen haben als erstes Zeichen Spezialbedeutung:
      Die schließende Klammer ] gilt an dieser Position als gewöhnliches
      Zeichen der Zeichensammlung. Das Circumflex ^ ist dort ein Invertierer.
      Das Minuszeichen verliert seine Bedeutung als Anzeiger eines
      Zeichenbereiches: vor und nach einem Zeichenbereich, oder am Anfang
      und am Ende der Zeichenklasse.

    Erweiterte Syntax XRE
      Zeichenklassen-Subtraktion -[ ]
       [a-z-[aeiou]]                    Selbstlaute werden subtrahiert (XRE)
       [b-df-hj-np-tv-z]                Selbstlaute werden weggelassen (ERE)
       [\p{Po}-[\d{128}-\d{255}]]       {Po} ohne die Zeichen ab 128
       [\d{128}-\d{255}-[äöüßÄÖÜ]]      Zeichen ab 128, ohne äöüßÄÖÜ
       [\w-[\x\l_]]                     entspricht [G-Z]
       [^A-Z-[a-z]]                     Invertierung hat Vorrang
       [^A-Z-[a-z]]                     entspricht [^A-Za-z]
       [^A-Z-[^a-z]]                    entspricht [a-z]
      Zeichenklassen-Intersektion &&
       [abcdef&&c-euvx]                 paßt zu c d e  (UND-Funktion)
       [1234&&23456&&0123]              paßt zu 2 3
       [abcdef&&[^c-e]]                 [ ] nur nötig für ^ Invertierung
       [a-z&&[^aeiou]]                  entspricht [a-z-[aeiou]]
       [^A-Z&&[aeiou]]                  Invertierung hat Vorrang
      Verschachtelung beliebig
       [a-z&&wjdh&&[^A-Z-[aeiou]&&hj]]  paßt zu h j

      Das Maskierzeichen ist innerhalb von Zeichenklassen [ ] speziell.
      Eine Folge von zwei Maskierzeichen (\\ oder %%) resultiert zu einem
      Maskierzeichen als gewöhnliches Zeichen.

    Vordefinierte Zeichenklassen
      Nur innerhalb einer Zeichenklasse: [[:posix:]]
      Alle anderen vordefinierten Zeichen und shorthand-Zeichenklassen
      können insbesondere auch außerhalb von [ ] verwendet werden.
      SYNTAX                   ENTSPRICHT
      \s                       [ \t\r\n\f\v]
      \S                       [^ \t\r\n\f\v]
      \d                       [0-9]
      \D                       [^0-9]
      \x                       [0-9A-Fa-f]
      \X                       [^0-9A-Fa-f]
      \o                       [0-7]
      \O                       [^0-7]
      \w                       [0-9A-Za-z_]
      \W                       [^0-9A-Za-z_]
      \h                       [A-Za-z_]
      \H                       [^A-Za-z_]
      \a                       [A-Za-z]
      \A                       [^A-Za-z]
      \l                       [a-z]
      \L                       [^a-z]
      \u                       [A-Z]
      \U                       [^A-Z]
      \N                       [^\n]

      POSIX: (nur innerhalb einer Zeichenklasse: [[:posix:]])
      [:alnum:]                [A-Za-z0-9]
      [:alpha:]                [A-Za-z]
      [:blank:]                [ \t]
      [:cntrl:]                00-1F 7F
      [:print:]                [ -~]
      [:graph:]                [!-~]
      [:punct:]                [!"#%&'*,./:;?@\_-()[]{}]
      [:space:]                [ \t\r\n\f\v]
      [:lower:]                [a-z]
      [:upper:]                [A-Z]
      [:digit:]                [0-9]
      [:xdigit:]               [0-9A-Fa-f]
      [:ascii:]                0000-007F
      [:word:]                 [0-9A-Za-z_]

      UNICODE:
      \p{IsBasicLatin}         0000-007F
      \p{IsLatin-1Supplement}  0080-00FF
      \p{Lu}                   A-Z C0-DE
      \p{Ll}                   a-z B5 DF E0-FF
      \p{Lo}                   AA BA
      \p{L}    Letter          {Lu} {Ll} {Lo}
      \p{Nd}                   0-9
      \p{No}                   B2 B3 B9 BC BD BE
      \p{N}    Number          {Nd} {No}
      \p{Pc}                   _
      \p{Pd}                   -
      \p{Ps}                   ( [ {
      \p{Pe}                   ) ] }
      \p{Pi}                   AB «
      \p{Pf}                   BB »
      \p{Po}                   ! " # % & ' * , . / : ; ? @ \ A1 A7 B6 B7 BF
      \p{P}    Punctuation     {Pc} {Pd} {Ps} {Pe} {Pi} {Pf} {Po}
      \p{Sm}                   + < = > | ~ AC B1 D7 F7
      \p{Sc}                   $ A2-A5
      \p{Sk}                   ^ ` A8 AF B4 B8
      \p{So}                   A6 A9 AE B0
      \p{S}    Symbol          {Sm} {Sc} {Sk} {So}
      \p{Zs}                   ' ' A0
      \p{Z}    Separator       {Zs}
      \p{Cc}                   00-1F 7F-9F
      \p{Cf}                   AD
      \p{C}    Control         {Cc} {Cf}

      UNICODE invertiert:
      \P{IsBasicLatin}
      \P{IsLatin-1Supplement}
      \P{Lu}
      ...
      \P{C}
      
    Vordefinierte Zeichen
      Alle vordefinierten Zeichen können auch außerhalb einer
      Zeichenklasse [ ] verwendet werden.
      \t       Tab              9
      \n       NewLine         10
      \v       VTab            11
      \f       FormFeed        12
      \r       CarriageReturn  13
      \e       Escape          27
      \cA \ca  Control chars    1
      \cB \cb                   2
      \cC \cc                   3
      \cD \cd                   4
      \cE \ce                   5
      \cF \cf                   6
      \cG \cg                   7
      \cH \ch                   8
      \cI \ci                   9
      \cJ \cj                  10
      \cK \ck                  11
      \cL \cl                  12
      \cM \cm                  13
      \cN \cn                  14
      \cO \co                  15
      \cP \cp                  16
      \cQ \cq                  17
      \cR \cr                  18
      \cS \cs                  19
      \cT \ct                  20
      \cU \cu                  21
      \cV \cv                  22
      \cW \cw                  23
      \cX \cx                  24
      \cY \cy                  25
      \cZ \cz  Control chars   26
      \c0                       0
      \c1                      27
      \c2                      28
      \c3                      29
      \c4                      30
      \c5                      31
      \c6                      32
      \c7                     127
      \c9                     255

    Frei definierbare Zeichenwerte
      Die nachfolgenden Umwandlungssequenzen können auch außerhalb einer
      Zeichenklasse [ ] verwendet werden.

      \d{255}  dezimal         0-255
      \o{377}  oktal           0-255
      \x{FF}   hexadezimal     0-255
      \u{00FF} hexadezimal     0-255

      Es liegt hier ein Konflikt mit den vordefinierten
      Zeichenklassen  \d \o \x \u  vor.
      Und zwar innerhalb und außerhalb einer Zeichenklasse [ ].
      Außerhalb von Zeichenklassen [ ] gibt es einen Konflikt mit dem
      Quantifizierer  {m}  {m,n}.

      Innerhalb einer Zeichenklasse [ ] ist lediglich eine konfliktfreie
      Abfolge der betroffenen Zeichen erforderlich, da die Reihenfolge
      hier fast keine Rolle spielt:  {\d}  oder  }{\d  oder  ...
      Es muß nur dafür gesorgt werden, daß direkt nach \d kein { folgt.

      Außerhalb von Zeichenklassen [ ]:
         SPEZIELL (Quantifiz.) :    {             \{
         Umwandlung wirksam    :  \d{123}       \d{123}
         Quantifizierer wirksam:  \d\,{123}     \d\{123}
         dito                  : [\d]{123}     [\d]\{123}
         Gewöhnliche Zeichen   :  \d\{123}      \d\,{123}
      Die Sequenz \, ist eine Nulloperation (nop, no operation).
      In den letzten drei Zeilen wirkt \d als Zeichenklasse.
      Als Gewöhnliche Zeichen sind { 1 2 3 } gemeint.


 ALTERNATIVEN

    Alternativen-Listen sind die wichtigste Eigenschaft, die die ERE
      gegenüber den BRE aufweisen.
           AK(fold|falg|senti|lokal)_(63|84)s
      Es ist ein natürlicher Bedarf an diesem Ausstattungsmerkmal erkennbar.
      Wenn darüber nicht verfügt werden kann, müssen Auswege gesucht werden.
      Dazu kann die Programmierbarkeit eines Shell-Programms dienen.
      Das interne grep-Kommando der bish kann bis zu acht RA entgegennehmen,
      die ODER- oder UND-verknüpft werden können.
           AK(fold|(yo\w{3,6}|tv)q|senti|[lL]okal)_(63|(?&num))s
      Eine Alternativen-Liste kann hunderte Zeichenfolgen enthalten.
      Es gibt keine prinzipiellen Einschränkungen bei der Ausgestaltung
      der jeweiligen Zeichenfolge.
      Die erste passende Zeichenfolge von links nach rechts wird verwendet.
           RA                                  DATEN         MATCH
           (?(DEFINE)(69|70))a(d|(?1))v        uxa70v        a70v
      Prüfung von IP-Nummern:
           ^(1\d\d|2[0-4]\d|25[0-5]|[1-9]\d|\d)\.(?1)\.(?1)\.(?1)$
           192.168.64.101
      Detailerklärungen siehe unten 'Subroutine Calls'.
    Parsen
      RA                              DATEN            HINWEIS
      "[^"]*"                         "abc"
      (?-b)"([^"\]|\\|\")*+"          "a\\bc\""
      "([^"]|\")*+"                   "a\\bc\""        fehlerhaft
      "(\"|[^"])*+"                   "a\\bc\""
      Meistens wird es so einfach gezeigt, wie im ersten Beispiel, jedoch das
      Parsen selbst einfachster Syntax-Konstruktionen ist selten ganz simpel.
      Das zweite Beispiel berücksichtigt wenigstens \\ und \" innerhalb einer
      String-"Konstante" (in C). Aber es gibt noch viel viel mehr.
      Das Maskierzeichen wurde zu % gewählt, weil in C als Kontrast \ gilt.
      Ohne diese Maßnahme müßte der RA so: "([^"\\]|\\\\|\\")*+" aussehen.
      Beim dritten Beispiel stiehlt die erste Alternative der zweiten
      Alternative das Zeichen \. Das vierte Beispiel ist korrekt, jedoch nicht
      maximal schnell, da meist die zweite Alternative passen muß.
      Die Alternativen der bish-XRE wurden auch aus den vorstehend erkennbaren
      Anlässen so konzipiert, wie sie konzipiert wurden, denn das gibt
      notwendige Steuerungsmöglichkeiten.


 GRUPPEN

    Standard-Gruppe
      RA            DATEN
      (abcd+e)      qqwoabcddddeimttuyy
                        ^       ^
      Die korrespondierenden Positionen beider Klammern in den DATEN werden
      gespeichert, sofern die angegebene Zeichenfolge in den DATEN vorkommt.
      Das sind hier die Positionen a und i, nicht a und e.
      Wenn es die erste speichernde Gruppe (capturing) im RA ist, wird
      die Referenznummer 1 zugewiesen.
      Von links nach rechts werden aufsteigende Nummern zugewiesen, alle
      speichernden Gruppen - jeweils die öffnende Klammer - betreffend.
      Nur diese und die nachfolgend beschriebene Gruppe speichern.
      Das Speichern dieser Gruppe kann per Option n deaktiviert werden.

      Mit Ausnahme der vier Lookaround-Gruppen können alle Gruppen der XRE
      beliebig quantifiziert werden!
      Bei gleichzeitiger Verschachtelung (abc(kw+){1,4}oi){0,6} ist allerdings
      eine Speicherung bei eingeschachtelten Gruppen weitgehend sinnlos.

    Benamte Gruppe
      (?<name>abcd+e)
      (?'name'abcd+e)
      Logischerweise ist dies ebenfalls eine speichernde Gruppe.
      Namensbildung:  [A-Za-z_][A-Za-z_0-9]*
      Eine Referenznummer wird genau so wie bei der Standard-Gruppe
      zugewiesen. Zusätzlich kann man sich später durch Angabe des Namens
      auf eine benamte Gruppe beziehen.
      Die einleitende Zeichenfolge (? gilt für alle zusätzlichen Gruppen
      und sonstige Klammer(?konstruktionen) der XRE.
      Der Beginn (\? startete eine Standard-Gruppe, falls ? ohne Maske
      speziell ist! Die Zeichen < ' > haben hier nur eine Kontextbedeutung,
      wobei < und > ihre normale Spezialbedeutung verlieren!

    Nicht speichernde Gruppe
      (?:abcd+e)
      Dieser Gruppe wird keine Referenznummer zugewiesen.
      Eine weitere Bedeutung hat diese Gruppe nicht.
      Es ist quasi die Standard-Gruppe ohne Speicherung.
      Bei den BRE und ERE kann die Speicherung bei ( ) nicht abgewählt werden.

    Possessive Gruppe
      (?>abcd+e)                      possessiver Inhalt
      (?:abcd+e){2,5}+                nur außen possessiv
      Die Elemente dieser Gruppe werden possessiv qualifiziert.
      Diese Gruppe ist eigentlich nur sinnvoll, falls eine RE-Engine
      individuelle Possessivität nicht bietet.
      Die Qualifizierung findet in Einschachtelungen ( ) hierin nicht statt.
      Dieses nicht in die Tiefe gehen bietet Steuerungsmöglichkeiten an.
      Das letzte Beispiel stellt eine Gruppe dar, deren Inhalt nicht
      possessiv ist, die sich aber als Ganzes possessiv verhält.

    Verzweigungs-Rücksetz-Gruppe
      (?|(abc)|(def)|(ghi))
         1     1     1                Referenznummern
      (?|(abc)(ABC)|(def)|(ghi))
         1    2     1     1           Referenznummern
         2    3     2     2           Referenznummern, mit zuvor ( )
      (?|(s)|(f))\1                   paßt zu ss und ff
      Diese Branch Reset Group wird durch (?| eingeleitet und speichert nicht.
      Falls diese Gruppe sinnvoll verwendet werden soll, sollte sie speichernde
      Gruppen nach dem vorstehenden Muster enthalten.
      Jede Alternative | setzt die Referenznummer auf denjenigen Wert zurück,
      der beim Eintritt in diese Gruppe vorlag.
      Egal, welche Alternative zutrifft - die Referenznummer ist voraussagbar.
      Beim letzten Beispiel ist der Referenzbezug \1 zu beachten.
      Bei benamten Gruppen innerhalb sollte der Name gleich sein für alle
      Gruppen, die die gleiche Referenznummer haben.

    Positive Look Ahead Gruppe
      RA                 DATEN          MATCH
      (?=abcd+e)
      qt(?=ykj)          abcqtykj       qt
      qt(?=ykj)ykj       abcqtykj       qtykj
      Diese Gruppe überspannt keine Zeichen aus den DATEN!
      Im Englischen gibt es den Begriff 'Zero-Length Assertion' dazu.
      Die Leseposition in den DATEN wird bei Gruppenende zurückgesetzt, auf
      denjenigen Punkt, der zu Beginn der Gruppe vorlag.
      Dadurch wird doppelt gelesen: oben gilt das für ykj im letzten Beispiel.
      Dies gilt für alle vier Lookaround-Gruppen.
      Auf das zweite Beispiel bezogen: nach qt muß ykj folgen, ohne daß
      dann ykj Bestandteil des Passens (Match) ist.

      Zum vim-Editor gibt es unter vielen anderen die Definition für das
      Highlighting einer C-Funktion name(args):
           syn match  cFunction  "\<[a-zA-Z_][a-zA-Z_0-9]*\>\s*("me=e-1
      Am Ende me=e-1 bedeutet: matchend = end-1
      Die Klammer ( muß vorhanden sein, soll aber nicht highlighted werden.

      Beispiel von der oben angegebenen Webseite:
      Es soll ein Wort gefunden werden, sechs Zeichen lang, welches irgendwo
      die Zeichenfolge cat enthält:

           cat\w{3}|\wcat\w{2}|\w{2}cat\w|\w{3}cat

      Das ist kaum noch realisierbar, wenn das Wort 6-12 Zeichen lang sein
      und die Zeichenfolgen cat, dog oder mouse enthalten soll.

           (?=\b\w{6}\b)\w*cat\w*

      Es wird mit Lookahead ein Wort{6} gesucht. Danach wird nochmals gelesen
      und die Folge  cat  darin gesucht.  (\b paßt zu Wortgrenzen)

           \b(?=\w{6,12}\b)\w{0,9}(cat|dog|mouse)\w*

      Vorstehend die Lösung des zuvor angesprochenen komplexeren Beispiels.
      Die Mächtigkeit des Lookaround-Konzeptes ist unschwer erkennbar.

    Negative Look Ahead Gruppe
      RA                 DATEN          MATCH
      (?!abcd+e)
      qt(?!ykj)          abcqtyKj       qt
      qt(?!ykj)          abcqt          qt
      Wie oben, nun allerdings darf ykj nicht(!) auf qt folgen.

    Positive Look Behind Gruppe
      RA                 DATEN          MATCH
      (?<=abcd+e)
      ^uxykj(?<=ykj)qt   uxykjqtabc     uxykjqt
         ykj(?<=ykj)qt   uxykjqtabc       ykjqt
      Bei den Lookahead-Gruppen muß einer Zeichenfolge in den DATEN
      eine bestimmte Zeichenfolge folgen, oder darf nicht folgen.
      Hingegen bei den Lookbehind-Gruppen muß eine bestimmte Zeichenfolge
      vor einer Zeichenfolge in den DATEN stehen, oder darf eben nicht
      vorangestellt sein.
            <--: . . . . . :-->
      Lookbehind           Lookahead
      Ein Lookbehind-Verhalten ist sehr problematisch zu implementieren, falls
      das Grundkonzept einer regex-Engine dafür ungeeignet ist.
      Lookbehind ist daher oft nicht oder nur in sehr schlechter Ausführung
      enthalten.
      Zu den Einschränkungen gehören:
      o  Nur Zeichenketten mit konstanter Länge erlaubt.
         Keine Quantisierung möglich.
      o  Wenn Alternativen, dann nur mit gleich langen Zeichenfolgen.
      o  Der Gruppeninhalt wird auf alle möglichen Längen untersucht, die
         er in den Daten potentiell überspannen kann.
      Die bish-XRE hat hier gar keine konzeptionellen Hürden, sondern kann
      den RA wie auch die DATEN temporär anders herum abarbeiten.
      Vor der Abarbeitung von rechts nach links muß überhaupt nichts
      analysiert werden.
      RA                                               DATEN / MATCH
      \w*(mouse|dog|cat)\w{0,9}(?<=\b\w{6,12})\b       sda,hmousegfhzx,lk
                                                           hmousegfhzx
                                                          h(mouse)gfhzx
      So kann denn auch der Beispiel-RA von Lookahead oben symmetrisch
      umgedreht werden für Lookbehind.
      Es sind allerdings absichtlich nicht sämtliche verschiedene RA-Einheiten
      um die Möglichkeit des Linksbetriebs erweitert worden.
      Gruppen sollen nicht quantifiziert, und Referenzen in Lookbehind nicht
      verwendet werden.

    Negative Look Behind Gruppe
      RA                   DATEN                       MATCH
      (?<!abcd+e)
      (?<!ykj)qt           yKjqtabc                    qt
      \b\w+(?<!ung)\b      Richtung,Verwendungen       Verwendungen
      Siehe oben Negative Look Ahead.
      Hier darf ykj nicht vorangestellt sein.
      Das letzte Beispiel zeigt eine Wortsuche, wobei das Wort nicht
      mit der Zeichenfolge 'ung' enden darf.
      Bei der Standard-Anwendung von Lookaround-Gruppen wird nichts
      hinter bzw. vor die Gruppe gestellt.
      Wenn jedoch das doppelte Lesen ausgenutzt werden soll, muß ein
      Anhängen bzw. Voranstellen von weiteren RA-Einheiten erfolgen.

    Konditionale Gruppe
      (?(bedingung)yes|no)
      (?(<name>)yes|no)           nicht implementiert
      (?('name')yes|no)           nicht implementiert
      (?(number)yes|no)           nicht implementiert
      (?(+number)yes|no)          nicht implementiert
      (?(-number)yes|no)          nicht implementiert
      (?(ausdruck)yes|no)
      (?(ausdruck)yes)
      RA                          DATEN      MATCH
       x(?(a)b|c)y                qxabyw     xaby
       x(?(A)b|c)y                qxacyw     xacy
       x(?(a)b)y                  qxabyw     xaby
       x(?(A)b)y                  qxayw      xay
       x(?(A)b)y                  qxAbyw     xAby
      Eine Reihe von Varianten wurde nicht implementiert, u.a. wegen der
      Uneindeutigkeit der vorgegebenen Syntax.
      Diese Gruppe prüft eine Bedingung (Kondition,condition) und durchläuft
      in Abhängigkeit des Prüfungsergebnisses den yes-Ausdruck oder den
      no-Ausdruck. Der no-Ausdruck darf weggelassen werden.
      Die Klammern bei (ausdruck) sind keine Gruppe, sondern (?( ist die
      Einleitung; die Klammern sind nur die Einrahmung für den Ausdruck.
      Es ist zu beachten, daß wenn die Bedingung nicht zutrifft, Zeichen
      aus den DATEN, die nicht passen, dennoch als angeblich passend
      im Gesamt-MATCH enthalten sind: hier a <> A
      Dieser Gruppe haften Einschränkungen an:
      Die Länge des Bedingungsausdrucks über die DATEN muß vorherbestimmbar
      sein; Es dürfen nur Einheiten mit fester Anzahl eingesetzt werden.
      Immerhin sind das:  [ ] [ ]{2}  a b c{3}  .. .{10}  \w \w{5}  \t
      RA                     DATEN            MATCH
      (?(aBiu{3})c|d)        qabiuuddy        qabiuud
      q(?(aBiu{3})c|d)       qabiuuudy        qabiuuud
      Das vorstehend erste Beispiel zeigt unerwünschtes Verhalten:
      Das q, gar nicht im RA enthalten, paßt nicht zum a. Deshalb springt
      die Verarbeitung sechs Zeichen (1+1+1+3) weiter, nach ddy.
      Die Verarbeitung soll ja nicht abbrechen wegen Nichtpassens, sondern
      mit dem no-Ausdruck weiter fortfahren.
      Fazit: Die Gruppe muß mit ihrem Bedingungsausdruck an eine DATEN-Position
      gebracht werden, wo sie auf einen Abschnitt trifft, den sie auch prüfen
      soll! Der Vorbau q im zweiten Beispiel sorgt dafür.

    Balancierende Gruppe
      (?<name1-name2>subexpression)
      (?<-name>subexpression)
      (((?'Open'\()[^\(\)]*)+((?'Close-Open'\))[^\(\)]*)+)*(?(Open)(?!))$
      ^[^<>]*(((?'Open'<)[^<>]*)+((?'Close-Open'>)[^<>]*)+)*(?(Open)(?!))$
      <abc><mno<xyz>>
      Diese Konstruktion ist in der Funktionsbibliothek .NET von Microsoft
      enthalten. Sie wurde in der bish-XRE nur in den Compiler implementiert.

    Startzeichen-Syntax
      (  )   --  Standard-Gruppe
      (?<        (?= 
      (?'        (?! 
      (?:        (?<=
      (?>        (?<!        (?(exp
      (?|        (?(         (?(<
      (?#        (?opt       (?('
      (?3        (?+1        (?-2
      (?&        (?R         (?0
      Eine klare Eindeutigkeit liegt leider nicht vor!
      Die ersten beiden Zeichen sind speziell: (?  \(?  (\?  \(\?
      Dann folgen fast immer ein drittes und manchmal ein viertes Zeichen, die
      eine eindeutige Erkennung an Hand der Startsequenz ermöglichen.
      Jedoch bei manchen Einheiten muß bis zu deren Ende geprüft werden, um
      sie erkennen und anerkennen zu können.
      Insbesondere bei (?[optionen][-^]optionen[:...])
      Das dritte und weitere Zeichen haben keine Spezialbedeutung.
      Falls sie eine haben, verlieren sie sie hier.
      Danach fungieren sie durch den gegebenen Kontext als Erkennungszeichen.
      Im Gegensatz zu den ersten beiden Zeichen (? dürfen die weiteren
      Erkennungszeichen nicht maskiert werden! Sie dürfen im x-Modus auch nicht
      abgetrennt werden, durch Einfügen von Zwischenraumzeichen.
      Der Start (\? beginnt eine Standard-Gruppe ( ) mit dem ? als erstem
      gewöhnlichen Zeichen, falls ? ohne \ als speziell konfiguriert wurde.


 KLAMMERKONSTRUKTIONEN

    Kommentare
      (?#comment)
      '(?#co)(?x)    ^a\,b $  #XC '    --    entspricht '^ab$'
      Der Kommentar '#XC ' und die anderen Zwischenraumzeichen werden durch
      den x-Modus ermöglicht. Dieser Kommentar reicht bis zum Zeilenende
      [\r\n]* einschließlich oder Ende des RA.

    Optionen
      (?bsminx-bsminx)    - deaktiviert folgende Optionen
      (?bsminx^bsminx)    ^ deaktiviert folgende Optionen
      (?-bsminx)
      (?bsminx)
      (?bi:regexp)        RA mit temporären Optionen bi
      (?x)                aktiviert den x-Modus
      Das Optionensetzen kann auch links vor einem Anker ^ vorgenommen werden.
       b    wählt den Backslash (\ statt %) innerhalb des RA
       s    Singleline-Modus  (default; wird ignoriert)
       m    Multiline-Modus   (wird ignoriert)
       i    unterscheide nicht zwischen A-Z und a-z (ignore case)
       n    die Standard-Gruppe ( ) speichert keine Referenz
       x    es können Zwischenraumzeichen eingefügt werden
      Die Zeilenmodi  s m  sind sinnlos mit den Kommandos grep und expr, da
      diese zeilenorientiert arbeiten und/oder keine Möglichkeit bieten, die
      Ergebnisse aus beliebig vielen Zeilen (m) mitzuteilen.
      Außerdem widersprechen sie dem rein binären Konzept der bish-XRE.
      Der Multiline-Modus bezieht sich auf die DATEN, nicht auf den RA.
      Option i erstreckt sich nur auf gewöhnliche Zeichen, nicht auf
      Zeichenklassen, wobei auch die Buchstaben des oberen Teils (>127)
      des Latin1-Zeichensatzes berücksichtigt werden.

      Der x-Modus gestattet es, Zwischenraumzeichen ( \t\r\n\f\v) an vielen
      Stellen des RA einzufügen, sofern dadurch keine speziellen Zeichenfolgen
      zerteilt werden. Mit dem x-Modus können mehrzeilige RA mit jeweiligen
      #Kommentaren vor dem Zeilenende geschrieben werden:
           (?xb)
           # Prüfung von IP-Nummern: 192.168.64.101
           ^(1[0-9][0-9]            # 1xx
            |2[0-4][0-9]            # 2xx
            |25[0-5]                # 25x
            |[1-9][0-9]             # xx ohne 0x
            |[0-9])                 # x
           \.(?1)\.(?1)\.(?1)$      # + 3 aufrufe
      Die Zwischenraumzeichen und # können im x-Modus mit dem Maskierzeichen
      zu gewöhnlichen Zeichen maskiert werden.


    Unterroutinen-Aufrufe (Subroutine calls)
      (?1)              Referenznummer 1
      (?1){m}           mit Quantifizierung
      (?+1)             relative Adressierung, nächste Gruppe
      (?-1)             relative Adressierung, vorherige Gruppe
      (?&name)          Angabe eines Referenznamens
      (?+1)(?'name'[abc])(?1)(?-1)(?&name)
                        fünf Buchstaben aus der Menge [abc]
      [abc](?'name'[abc])[abc][abc][abc]
                        entspricht dem Vorstehenden
      Diese Konstruktionen lassen die Inhalte speichernder Gruppen ablaufen.
      Bei diesen Aufrufen sind Vorwärtsreferenzen möglich.
      Andere Quantifizierungen als {m} sind logischerweise nicht möglich.
      Rekursive Aufrufe sollten vermieden werden!
      Diese Aufrufe sind etwas gänzlich Anderes als die 'Rückreferenzen'.
      ^(1[0-9][0-9]|2[0-4][0-9]|25[0-5]|[1-9][0-9]|[0-9])\.(?1)\.(?1)\.(?1)$
      7.8.122.255
      ^(1[0-9][0-9]|2[0-4][0-9]|25[0-5]|[1-9][0-9]|[0-9])\.\1\.\1\.\1$
      122.122.122.122
      Vorstehend eine Prüfung von IP-Nummern, gefolgt von einer Prüfung mit
      demonstrativen Rückreferenzen \1.

    Unterroutinen-Definition
      (?(DEFINE)(?'name'regexp))
      ab(?(DEFINE)(?<name>regexp))cd        paßt zu abcd
      (?&name)                              Aufruf
      Der Inhalt sind speichernde Gruppen, damit später ein Bezug durch einen
      Unterroutinen-Aufruf hergestellt werden kann. Andere Bezüge (\1 $1)
      sollten nicht hergestellt werden.
      Als Ganzes tritt diese Definition nicht in Erscheinung, sie ist mit ihrem
      Inhalt 'versteckt'.
      Eine solche Definition ist nicht notwendig, um Unterroutinen-Aufrufe
      verwenden zu können! Dazu reichen normal sichtbare Gruppen aus.

    Rekursion
      (?R)
      (?0)
      a(?R)z           paßt zu  aazz  aaaazzzz  az  ...
      Diese Konstruktion ist in der bish-XRE nur im Compiler implementiert.
      Sie erfaßt den gesamten RA.
      Dies ist eine (kleinere) Alternative zur 'Balancierende Gruppe'
      (siehe oben), so ähnlich wie \K anstelle der Lookbehind-Gruppen.


 EINZELNE MERKMALE

    Siehe hierzu auch oben die Sektion ZEICHENKLASSEN.
      Dort sind viele RA-Einheiten beschrieben, die auch außerhalb von
      Zeichenklassen anwendbar sind und somit auch hierhin passen würden.

    Wortgrenzen
      \b              paßt zu einer Wortgrenze (boundary)
      \B              paßt zu einer Position ohne Wortgrenze
      \<              paßt zu einem Wortbeginn ..[A-Za-z_]
      \>              paßt zu einem Wortende
      Diese Einheiten überspannen keine Zeichen in den DATEN (zero length).
      In den Daten müssen aber bestimmte Zeichenabfolgen vorliegen, damit diese
      Einheiten passen. Und zwar muß ein Übergang von einem Zeichen, das nicht
      zu der Menge der Wortzeichen gehört, zu einem Zeichen, das zu der Menge
      der Wortzeichen gehört, vorhanden sein - oder umgekehrt.
      Die Besonderheit der Einheit \< ist, daß nur ein Wortbeginn paßt, der aus
      einem Nameführungszeichen (Head) besteht:  ;[A-Za-z_][A-Za-z_0-9]*
      Statt \< \> kann < > konfiguriert werden.

    Rückreferenzen
      \1 \2 \3 \4 \5 \6 \7 \8 \9
      \k<name>     \k'name'     \k{name}
      \k<nummer>   \k'nummer'   \k{nummer}
      \k<-nummer>  \k'-nummer'  \k{-nummer}
      \g<name>     \g'name'     \g{name}
      \g<nummer>   \g'nummer'   \g{nummer}
      \g<-nummer>  \g'-nummer'  \g{-nummer}
      \1*  \1+  \1{2,5}?
      Diese Referenzen beziehen sich auf eine vorhergehende speichernde Gruppe.
      Genau derjenige Bereich in den DATEN, zu dem eine speichernde Gruppe
      paßt, muß auch an der Stelle der Rückreferenz hinsichtlich einer
      genau übereinstimmenden Zeichenfolge vorliegen!
      Rückreferenzen können einschränkungslos quantifiziert und qualifiziert
      werden. Vorwärtsreferenzen (+nummer,nummer) sind nicht möglich.
      RA                 DATEN             MATCH
      ^(.+)\1\1$         jajaja
      ^(.+)\1\1$         neinneinnein
      ^(.+)\1\1$         tiptiptip
      ^(.+)\1\1$         iiiiiiiii
      ^(.+)\1{2}$        ,,,
      ^(.*)\1\1$
      (.*)\1\1da         da                da
      Die ersten vorstehenden RA passen zu sämtlichen DATEN, die aus drei
      gleichen aneinanderstoßenden Teilen bestehen. Das sind praktisch
      unendlich viele.
      Dreimal diese Dokumentationsdatei hintereinander verkettet, würde auch
      passen! Tatsächlich ist das eine ganz einfache Aufgabe für das Kommando
           expr DATEIx3 xv:: '^(.+)\1\1$'
      Der vorletzte angegebene RA paßt auch zu drei leeren Zeichenfolgen,
      folglich zu leeren DATEN.
      Beim zuletzt angegebenen RA wurde .* mißbraucht; man erhält ein zumeist
      unerwartetes Resultat. Verwendung von .+ repariert dies Verhalten.
      RA                              DATEN              MATCH
      ^(?<rr>.+)(\k<rr>{1,2})da       tototototoda       --
      ^(?<rr>.+)(\k<rr>{1,2})da       totototototoda     (tototo)(tototo)da
      ^(?<rr>.+)(\k<rr>{1,8})da       tototototoda       (to)(totototo)da
      Solchermaßen unbestimmte RA sollten nicht konstruiert werden.
      Ohne Anker ^ paßt praktisch alles. Man wundert sich.
      Die Maschine geht dazu über, immer längere Stücke aus den Daten als
      Einheit zu betrachten. Kein Wunder, denn .+ hindert sie nicht daran.
      Beim letzten RA ist erkennbar, daß die Maschine durch das zuvor geringe
      Maximum ,2} gehindert wurde, ein Passen herzustellen.
      Achtung, {0,n} paßt immer irgendwo hin!
      Hinweis: \1  \1{2}  sind beide ohne Qualifizierer + possessiv.
      Deshalb und wegen der Anker ^ $ ist der RA oben bei jajaja sicher
      anwendbar.
      Rückreferenzen müssen keineswegs aneinanderstoßende Regionen definieren.
      Zwischen ihnen darf beliebige und beliebig viel andere Syntax stehen.
      Auch Rückreferenzen zu anderen speichernden Gruppen.

    Wiederholung des Passens
      \G
      abc\Giuv              entspricht abc(iuv)+
      a|bc\Gwg|kalt
      (dsa\Gqz)
      Die oben notierte Entsprechung ist keine speichernde Gruppe;
      \G speichert nicht.

    Keep_Out
      \K
      abc\Kiuv
      ass|bc\Kwg|kalt\Koi
      (dsa\Kqz)
      Diese Funktion ist ein gewisser Ersatz für eine Lookbehind-Gruppe.
      Der Beginn des Passens des RA wird nach rechts verschoben; der Teil
      links von \K wird draußen gehalten (keep out).

    Maskierter Bereich
      \Q .. \E
      \Qsh{d\\h3*3(3)\38]3[2&%@25\E       25 Zeichen
      \Qa\kw\E\\E\Qq\ui\E                 entspricht a\\kw\\Eq\\ui
      Alle Zeichen zwischen \Q und \E werden eins nach dem anderen
      ohne Interpretation als gewöhnliche Zeichen gespeichert.
      Die Folge \E kann nicht in diesem Bereich stehen, sondern
      der Bereich \Q..\E muß zu diesem Zweck unterbrochen werden.

    Nulleinheiten
      Die folgenden Einheiten sind vollkommen wirkungslos
      im Hinblick auf den kompilierten RA.
      (?#comment)     Kommentar
      (?#)            leerer Kommentar
      \,              kürzer, auch innerhalb [ ]
      Diese Einheiten können dazu dienen, Syntax-Sequenzen zu zerteilen, damit
      diese zu gewöhnlichen Zeichen oder anderen Einheiten zerfallen.


 SUBSTITUTION

    In einem Text-Editor ist möglicherweise ein Mechanismus
      'Suchen_und_Ersetzen' vorhanden.
      Der kann sich folgendermaßen darstellen:

           :g/abc/s/rtv/\U=&:/g

      In allen Zeilen, die abc enthalten, sollen alle Vorkommnisse (/g)
      von rtv durch =RTV: ersetzt werden.
      Die bish-XRE bzw. das interne Kommando expr(K) bietet eine solche
      Möglichkeit:

    Syntax
      $$                  $ als gewöhnliches Zeichen
      $_                  Einsetzen der (gesamten) DATEN
      $0  $&              Einsetzen des RA-Gesamt-Match
      $`                  Einsetzen des Teils links vor dem Gesamt-Match
      $'                  Einsetzen des Teils rechts nach dem Gesamt-Match
      $1 .. $9            Einsetzen der Rückreferenzen 1 bis 9
      ${nummer}           Einsetzen einer Rückreferenz mit Nummer 1..128
      ${name}             Einsetzen einer benamten Rückreferenz
      ${$name}            Einsetzen des Inhalts einer Shell-Variablen @
      ${*liste*anzahl}    Multiples Einsetzen des Inhalts von Einheitenlisten @
      $U                  Umwandlung zu Großbuchstaben
      $L                  Umwandlung zu Kleinbuchstaben
      $I                  Umwandlung aller Wörter zu Wwwwww
      $F                  Umwandlung aller Einsetzungen zu Eeeeee
      $E                  Deaktivierung der Modi $[ULIF]
      $d{255}             Umwandlung einer Ziffernkette zu einem Byte-Wert
      $o{377}             Umwandlung einer Ziffernkette zu einem Byte-Wert
      $x{FF}              Umwandlung einer Zeichenkette zu einem Byte-Wert
      $u{00FF}            Umwandlung einer Zeichenkette zu einem Byte-Wert
      $t                  Einsetzen eines TAB
      $r                  Einsetzen eines CR
      $n                  Einsetzen eines NL

      Das Zeichen $ ist als einziges global speziell.
      Insbesondere die mit @ gekennzeichnete Syntax wurde für bish-XRE kreiert.
      Bei der Syntax  ${*liste*anzahl}  darf 'liste' die gesamte vorstehende
      Syntax enthalten, auch rekursiv ${*abc*123} selbst, beliebig tief!
      Die 'anzahl' umfaßt den Wertbereich 0 .. 999999999.

      Das Zeichen * muß bei Verwendung in 'liste' doppelt ** gesetzt werden.
      Bei multiplem Ersetzen verändert sich zum Beispiel der Dateninhalt von
      $_ fortlaufend, denn die neuen DATEN beginnen jeweils hinter dem letzen
      Passenden bzw. hinter der letzten Ersetzung.

           arg0  arg1       arg2  arg3  arg4  arg5

           expr 'abcdecfhc' x:   'c'    +=   '++'
           ab++de++fh++

      Vorstehend arg1 sind die DATEN, arg3 der RA, arg4 (+) bewirkt, daß jedes
      Vorkommnis ersetzt werden soll, und (=) schaltet alle eventuellen
      Spezialbedeutungen der Zeichen in arg5 (Einsetzungstext) ab.

    Beispiele

           expr abcdecfhc x: 'c' + ''
           abdefh

      Löschen des Passenden wird durch leeren Einsetzungstext vorgenommen.

           expr abcdecfhc x: 'c'  '$IxYYG,hg,lKJ,jHHJ'
           abXyyg,Hg,Lkj,Jhhjdecfhc

      Hier wurde nur das erste Vorkommnis von c ersetzt.
      Die Funktion $I erfaßt nur die Einsetzung für das erste zu ersetzende c.

           expr abcdecfhc x: 'c(fh)'  '+C$1.$1-'
           abcde+Cfh.fh-c

      Vorstehend wurde eine Gruppen-Rückreferenz $1 benutzt.

           expr abcdecfhc x: 'c' + '${*${*top*10}$n*2}'

           abtoptoptoptoptoptoptoptoptoptop
           toptoptoptoptoptoptoptoptoptop
           detoptoptoptoptoptoptoptoptoptop
           toptoptoptoptoptoptoptoptoptop
           fhtoptoptoptoptoptoptoptoptoptop
           toptoptoptoptoptoptoptoptoptop

      Hier wurde erneut dreimal c ersetzt.

           expr abcdecfhc x:ABC 'c' + '${*${*top*10}$n*1000000}'

           echo ${#ABC}
            93000006
           echo "$__MEM__"
            VARBUF      49152   100663296   536870912    16777216    12906496

      Vorstehend wurde die bish-Variable 'ABC' mit 93000006 Bytes gesetzt.
      Das sind  2+(3*10+1)*1000000 + 2+(3*10+1)*1000000 + 2+(3*10+1)*1000000

           expr 'abc' x: ''  = '---'
           ---abc
           expr 'abc' x: '^' = '---'
           ---abc
           expr 'abc' x: '$' = '---'
           abc---

      Leeren Raum vorne und hinten ersetzen (Daten vorsetzen/anfügen).

           expr '' x: ''  '${*top*3}'
           toptoptop

      Dies Kommando kann auch einfach als Byte-Folgen-Generator genutzt werden.
      Zwei leere Argumente sind nützlich, wenn Daten wirklich nur generiert
      werden sollen.

           expr abcdecfhc x: 'dec(..)'
           fh

      Sehr wichtig ist auch die vorstehende Funktion mit drei Argumenten, die
      alle Zeichen zwischen allen gespeicherten Positionen ( ) ausgibt.
      Ausgabe kann auch in eine Variable (x:NAME) erfolgen.

           while readl Z
           do
              expr Z xv:: '^T_[0-9a-z_]{2,}$' || continue
              expr Z xv:W '^T_([0-9a-z_]{4})' && catv W /%n
              # ...
           done

      Vorstehend eine typische Anwendung, von denen in den zurückliegenden
      zwanzig Jahren etwa 3000 entstanden sind.

           #cp437 to Latin1
           Trans='
           80 c7
           81 fc
           .. ..
           fd b2
           '
           local Z:.200 qq=.. zz=.. q=. z=.

           while readl Z
           do
              for 2 qq zz in $Trans
              do
                 base -16 qq +b q
                 base -16 zz +b z
                 expr "$Z" :Z "$q" += "$z"
              done
              catv Z /%n
           done

      Eine Zeichensatz-Übersetzung von CP437 nach Latin1 per bish vorstehend.
      Dabei wurden BRE verwendet. bish-XRE verlangt x:Z als zweites Argument.

                 expr "$Z" x:Z '\x{'"$qq"'}' +=  '$x{'"$zz"'}'

                 expr "$Z" x:Z  "\\x{$qq}"   += "\$x{$zz}"

      Mit XRE könnten die Hex-Sequenzen direkt eingebaut werden.
      Das Kommando base entfällt dadurch.

           :23,126!cp437_latin.bish

      Im vim-Editor kann dieses Skript wie vorstehend aufgerufen werden, und
      die angegebenen Zeilen :von,bis werden übersetzt.

           grep -Xn -e '[%d{128}-%d{255}-[äöüßÄÖÜ]]' /u/bish/man/?*.mn?

      Aufgrund des vorstehenden Kommandos werden alle passenden Zeilen aller
      relevanten Dateien mit Dateiname und Zeilennummer ausgegeben.
      Und zwar werden alle Zeilen gesucht, die Zeichen aus der oberen Hälfte
      des Zeichensatzes enthalten, wobei nach [äöüßÄÖÜ] nicht gesucht wird.
      Das Maskierzeichen ist hier % (default).

           (?b)[\d{128}-\d{255}-[äöüßÄÖÜ]]

      Das Maskierzeichen wurde vorstehend zu \ gewählt.


 HINWEISE / WARNUNGEN

    Verwendung möglichst vieler gewöhnlicher Zeichen im RA erhöht die
      Sicherheit, daß der RA so arbeitet, wie es beabsichtigt ist.
      Verkoppelungen mittels Anker erhöhen ebenfalls diese Sicherheit.
      Zudem wird dadurch die Verarbeitungsgeschwindigkeit gesteigert.
      Die RA-Einheit  .*  wird oft mißbraucht. Unbestimmter geht es nicht!
      Dennoch kann  .*  auch sicher funktionierend eingesetzt werden:
           /fkp/elem/qm.txt        ^.*/([^/]+)$'
                    /qm.txt        ^.*/([^/]+)$'
                                       (qm.txt)
      Die Situation ist wegen ^ / $ eindeutig. Insbesondere / ist eine
      Konstante, die vorhanden sein muß und auch ein Ankerpunkt ist.
      Mit der possessiven Einheit .*+ vorne gibt es kein Passen.
      Eine Prüfung auf korrekte Pfadnamensyntax ist dies bei weitem nicht.
           (/[^\d{0}/]{0,254}){1,48}
      Vorstehender RA kommt dem schon sehr nahe: unter Unix sind alle Zeichen
      außer Null und / für einen Verzeichnis- und Dateinamen erlaubt, in
      beliebiger Abfolge.
    Testen
      Das Schreiben Regulärer Ausdrücke kann mit dem Programmieren in einer
      Programmiersprache verglichen werden.
      Daher sollte ein (vermeintlich) fertiger RA auch getestet werden!
    Possessiv
       qabcdedededekz    abc((de){1,2}){1,3}k    (1)
       qabcdedededekz    abc((de){1,2}de){1,3}k  (2)
      Beide RA passen zu weit mehr als zehn Folgen 'de', funktionieren also
      nicht so, wie multiplikativ prognostiziert.
      Zunächst ist erkennbar, daß beide RA unsinnig sind:
                         abc(de){1,6}k           (1a)
                         abc((de){2,3}){1,3}k    (2a)
                         abc(de){2,9}k           (2b)
      Vorstehend eine Umformung zu RA ohne unnötige Verschachtelung.
                         abc((de){1,2}+){1,3}+k
                         abc((de){1,2}+de){1,3}+k
      Beide RA wurden nun possessiv qualifiziert, und funktionieren dadurch
      wie beabsichtigt, obwohl sie unsinnig formuliert sind.
      Der zweite RA paßt also zu maximal neun 'de' (dedededededededede).
      Durch die Verhandlungen zwischen den verschachtelten Gruppen kommt es
      zu einem Passen eines zu langen Stückes aus den DATEN.
      Solche verschachtelten Gruppen erwarten eine Struktur mit Eckpunkten:
           abcggdefgdedeffkz    abc(g+(de){1,2}f+){0,2}k
      Dieser RA paßt auch ohne Possessivität.
      Verschachtelte Gruppen, die gleichzeitig explizit nicht possessiv
      quantifiziert sind, sollten besonders gründlich durchdacht und getestet
      werden.
    Immenser Zeitbedarf
      RA                DATEN                       ZEIT
      (x+x+)+y          xxxxxxxxxxxxxxxxxxxxxy      0,000 s
      (x+x+)+y          xxxxxxxxxxxxxxxxxxxxxZ      0,800 s
      (x+x+)+y          xxxxxxxxxxxxxxxxxxxxxxZ     1,648 s
      (x+x++)+y         xxxxxxxxxxxxxxxxxxxxxxZ     0,000 s
      Der Zeitbedarf steigt progressiv an mit der Anzahl der Zeichen x in den
      DATEN, wenn der RA nicht paßt.
      Der RA ist unsinnig komplex, wie beim vorstehenden Beispiel 'Possessiv'.
      Er entspricht  x{2,}y  ohne diesen Zeitbedarf.
      Wie im letzten Beispiel zu sehen ist, beseitigt Possessivität auch hier
      das problematische Verhalten. Die hier gesuchten DATEN verlangen keine
      Verhandlungen zwischen den RA-Einheiten.
    Null Vorkommnisse
           DATEN            RA                    MATCH
           asqqeonpi        er|(de){0,2}|n        ()
           asqqeonpi        er|n|(de){0,2}        ()
           asqqeonpi        er|(de){1,2}|n        n
      0-mal 'de' vorne paßt einwandfrei. (Der Quantifizierer ? = {0,1} sollte
      hier nicht vergessen werden.)
      Die Maschine vergleicht zuerst das 'a' ganz vorne. Und zu dem paßt
      0-mal 'de', also leer, als einziges sofort.


 LIMITIERUNGEN
    Verschachtelung
      Bei nachfolgenden Angaben hierzu gilt auch Ebene 0 als
      Verschachtelungsebene.
    Namen
      Deren Länge darf 31 Zeichen betragen.
    Referenzen
      Es werden die Nummern 1 .. 128 zugeordnet.
    Zeichenklassen
      Es können bis zu 48 freie Definitionen [ ] erfolgen.
      Vordefiniert sind 82 Zeichenklassen.
    Gruppen-Quantifizierung
      ( ){m,n}
      ( )*
      ( )+
      Die Werte m und n sind auf 30000 begrenzt.
      Bei Verwendung von * und + wird intern entsprechend begrenzt.
    Quantifizierte Gruppen
      können bis zu 4-fach verschachtelt werden.
    Unterroutinen-Aufrufe
      können bis zu 6-fach verschachtelt werden.
    Alternativen-Listen  (a|b|c)
      können sich innerhalb der ersten 8 Verschachtelungsebenen befinden.
    Konditionale
      können nicht verschachtelt werden.
    Verschachtelungstiefe
      Allgemein beträgt diese maximal 255.


 VERSIONEN
      XRE-Doku, Version August 2015
      bish-XRE, Version 0.95, August 2015


 SIEHE AUCH
      bish(K), expr(K), grep(K), regexp®
      http://www.regular-expressions.info/tutorial.html

 AUTOR
      Copyright © Helmut Schellong
      Vlotho, Juli 2015


 BEISPIELE
      Nachfolgend kommentarlose Beispiele, hier am Ende der Datei, weil
      der Umfang sehr groß ist. Es handelt sich um BRE-Ausdrücke
      mit dem Maskierzeichen %.

    2750 Beispiel-Zeilen




^

 regexp®                                                            regexp®



 NAME
      regexp - Definition der Schreibweise sogenannter regulärer Ausdrücke
               (regular expressions) und beim Zeichenmustervergleich
               (pattern matching).



 BESCHREIBUNG
      Ein regulärer Ausdruck ist ein Mechanismus zur Feststellung der
      Position einer ganz bestimmten Zeichenfolge oder um ein solches
      Muster gezielt zu manipulieren.
      Dieser Mechanismus wird von vielen Hilfsprogrammen unterstützt.
      Zeichenmustervergleich wird von Shell- und anderen Programmen zur
      Verfügung gestellt, hauptsächlich zur Dateinamen-Expansion.

      Diese Beschreibung regexp® umfaßt
                Elementare reguläre Ausdrücke
                Erweiterte reguläre Ausdrücke
                Zeichenmustervergleich

      Abweichungen von den folgenden Regeln zu Schreibweise und Konstruktion
      sind bei den Einzelbeschreibungen der betreffenden Kommandos erklärt.
      Nachfolgend wird das Backslash-Zeichen (\) als Sonderzeichen benannt;
      man achte darauf, ob andere Beschreibungen hiervon abweichend das
      Prozentzeichen (%) benennen.

      Vergleiche basieren stets auf dem Bitmuster, also dem Zahlenwert
      der Zeichen und nicht auf der graphischen Repräsentation der Zeichen.


 ELEMENTARE REGULÄRE AUSDRÜCKE (RA)

    RAs, die für ein einzelnes Zeichen stehen
      Die folgenden RAs ersetzen ein einzelnes Zeichen oder ein einzelnes
      Zeichen aus einer Ansammlung von Zeichen:

      Gewöhnliche Zeichen
      Ein gewöhnliches Zeichen ist ein RA, der für sich selbst steht.
      Ein solches Zeichen ist jedes beliebige Zeichen aus dem unterstützten
      Zeichensatz, außer NL (newline) und denjenigen Zeichen, die innerhalb
      eines RA Spezialbedeutung haben und unten aufgelistet sind.
      Eine Zeichenfolge, die aus einem Backslash (\) und dann einem der
      der folgenden Zeichen besteht, wird als Spezialsymbol interpretiert:
                ( ) { } 1 2 3 4 5 6 7 8 9

      Spezialzeichen
      Spezialzeichen haben eine Spezialbedeutung innerhalb von RAs,
      das heißt, sie enthalten eine bestimmte Funktionalität.
      Ein vorangestellter Backslash hebt die Spezialbedeutung eines Zeichens
      auf - das Zeichen steht dann für sich selbst.
      Diese Spezialzeichen und die Umgebungen, in denen sie Spezialbedeutung
      haben, sind:

           . [ \          Spezial, jedoch nicht innerhalb einer
                          Zeichenklasse ([...])

           *              Spezial, jedoch nicht innerhalb einer Zeichenklasse,
                          als erstes Zeichen eines RA und als erstes Zeichen
                          nach der Zeichenfolge  \(

           ^              Spezial, nur als erstes Zeichen eines RA
                          und als erstes Zeichen einer Zeichenklasse.

           $              Spezial, nur als letztes Zeichen eines RA

           begrenzer      Jedes Zeichen, das einen RA begrenzt, ist spezial
                          für denjenigen RA  (i.d.R. / und ?)

      Punkt

      Ein Punkt (.) außerhalb einer Zeichenklasse ersetzt ein beliebiges
      Zeichen außer NL.

    Zeichenklasse
      Eine Zeichenklasse, eingeschlossen in eckige Klammern ([ ]), ist
      ein RA, der ein einzelnes Zeichen ersetzt, das in der nichtleeren
      Ansammlung aus Zeichen vorkommt, die eine Zeichenklasse repräsentiert.
      Wenn also während einer Vergleichsoperation ein Zeichen aus dem zu
      prüfenden Vergleichsmuster mit einer Zeichenklasse verglichen wird
      und dieses Zeichen eines der Zeichen ist, die von der Zeichenklasse
      repräsentiert werden, dann gilt dieser Vergleich als zutreffend.

      Folgende Regeln bestehen zu Zeichenklassen:

           Das Zeichen NL wird von einer Zeichenklasse niemals repräsentiert.

           Innerhalb einer Zeichenklasse haben nur die Zeichen  ^ ] -
           Spezialbedeutung, ^ nur direkt nach der Startklammer [  .
           Die Zeichen  . * \ [  verlieren hierin ihre spezielle Bedeutung.

           Standardmäßig repräsentiert eine Zeichenklasse genau diejenigen
           Zeichen, die zwischen den beiden eckigen Klammern angegeben
           sind, wobei die Art der Darstellung keine Rolle spielt.
           Wenn jedoch das erste Zeichen nach  [  das Zeichen  ^  ist,
           werden diejenigen Zeichen repräsentiert, die NICHT angegeben sind.

                [abc]     paßt zu  a oder b oder c.
                [^abc]    paßt zu allen Zeichen,
                          außer zu  a und b und c und NL.

           Das Abschlußzeichen  ]  verliert diese Bedeutung, wenn es dem
           Startzeichen  [  oder  [^  direkt folgt.
           Es gilt in diesem Fall als gewöhnliches Zeichen.

           Das Minuszeichen (-) dient dazu, um per Kurzschreibweise
           Zeichenbereiche darzustellen.
           Es verliert seine Spezialbedeutung, wenn es an den Rändern,
           also nach  [  oder nach  [^  oder vor  ]  steht, oder wenn es
           das rechte Zeichen eines Zeichenbereiches ist.
           Es gilt in diesen Fällen als gewöhnliches Zeichen.
           Der Zahlenwert des rechten Zeichens eines Zeichenbereiches
           muß gleich oder größer als der Wert des linken Zeichens sein.

                [a-dU-Z]     entspricht  [abcdUVWXYZ]
                [^a-dU-Z]    entspricht  [^abcdUVWXYZ]
                [a-d-f]      entspricht  [a-dd-f]

                [-ac]        sind gleichwertig und passen zu
                [ac-]        a oder c oder -
                [-ca]
                [ca-]

                [#--]        paßt zu  # bis -  einschließlich
                [--@]        paßt zu  - bis @  einschließlich
                [a#--f]      paßt zu  a oder (# bis -) oder f


    RAs, die mehrere Zeichen ersetzen
      Sie werden konstruiert aus RAs, die ein Zeichen ersetzen.

        RARA        Beispielsweise  bc  paßt zum ersten Vorkommen von  bc
                    in  abcdefabcdef:  zweites und drittes Zeichen.
                    Ein RA sucht generell Übereinstimmung mit der
                    ERSTEN und LÄNGSTMÖGLICHEN Zeichenfolge.

        RA*         Ersetzt null oder mehr (beliebig viele) Vorkommen von RA.
                    b*c  oder  bbb*c  oder  bbbc
                    ersetzen das zweite bis fünfte Zeichen in
                    abbbcdeabbbbbbcde  .
                    Der Stern (*) verliert seine Spezialbedeutung als
                    erstes Zeichen eines RA.

        \(RA\)      Unterausdruck
                    Ein RA als Unterausdruck paßt zu allem, was ohne die
                    Zeichenfolgen  \( und \)  passen würde.
                    Unterausdrücke können verschachtelt werden.
                    Ein Stern (*) nach  \(  verliert seine Spezialbedeutung.
                    Nach  \)  ist ein Stern nicht erlaubt.

        \n          Die Zeichenfolge  \n  steht für einen Unterausdruck,
                    der zuvor mittels \( und \) definiert wurde.
                    n muß ein Digit von 1 bis 9 sein, das den RA adressiert,
                    der zwischen der n-ten Zeichenfolge \( und der
                    korrespondierenden Zeichenfolge \) steht.
                    ^\(.*\)\1$
                    paßt beispielsweise zu einer Zeile, die zwei gleiche
                    Zeichenketten hintereinander enthält.
                    Und zwar irgendwelche zwei gleiche Zeichenketten!
                    Nach  \n  kann ein Stern (*) stehen, der dann zu
                    null oder mehr Vorkommnissen des Unterausdrucks
                    multipliziert.
                    \(ab\(cd\)ef\)T\2*T\1  paßt beispielsweise zu
                    abcdefTcdcdTabcdef

                    Unterausdrücke sind äußerst sinnvoll bei den Kommandos
                    vi, ed, sed und expr(K).
                    Vorher:
                         Array[sel][1]
                         Array[i][0]
                         Array[esnu][0]
                    Im vi-Editor:
                    :g/Array\[\([a-z].*\)\]\[\([01]\)\]/s//Array[\2][\1]/
                    Nachher:
                         Array[1][sel]
                         Array[0][i]
                         Array[0][esnu]
                    Man kann so stundenlange Arbeit durch 2 Minuten ersetzen!

        RA\{m,n\}   Die Spezialfunktion des Stern (*) wird durch \{m,n\}
                    erweitert. (\{m,n} ist auch möglich.)
                    Mittels  m  und  n  wird angegeben, wie oft
                    mindestens und wie oft maximal RA vorkommen darf,
                    damit ein Vergleich zutreffend ist.
                    Für m und n ist ein Bereich von 0 bis 255 gültig.
                    \{m\}       m Vorkommnisse
                    \{m,\}    >=m Vorkommnisse
                    \{m,n\}   >=m,<=n Vorkommnisse

                    b\{3\}      paßt zum zweiten bis vierten,
                    b\{3,\}     zum zweiten bis achten, und
                    b\{3,5\}c   zum vierten bis neunten Zeichen von
                    abbbbbbbc


    Positionsfixierung eines RA
      Ein RA kann in Bezug auf das zu prüfende Vergleichsmuster
      in seiner Position festgelegt werden:

           Das Zeichen  ^  zu Beginn eines RA erzwingt, daß der RA
           beginnend vom Anfang einer Zeile an passen muß.
           Das Zeichen  $  am Ende eines RA erzwingt, daß der RA
           am Ende einer Zeile passen muß.
           Bei Verwendung beider Fixierungszeichen muß der RA
           am Anfang und am Ende einer Zeile passen.
           Hier passen also nur komplette Zeilen, von NL bis NL bzw. CR-NL.
           ^$  paßt nur zu Leerzeilen.



 ERWEITERTE REGULÄRE AUSDRÜCKE (ERA)

    Die wesentlichen Erweiterungen, die ERAs gegenüber den RAs bieten,
    sind die Klammern (), um zusammengefaßte Einheiten zu bilden,
    und der Oder-Operator | für die Alternativ-Funktion.

    Die Spezialzeichenfolgen der RAs  \( \) \{ \} \1 bis \9
    gelten hier nicht.  \{m,n\}  wird teilweise durch die hier gültigen
    hinzugekommenen Spezialzeichen + und ? aufgewogen.
    ERAs sind zumindest für Editor-Programme nicht so gut geeignet
    wie die (einfacheren?) RAs.

    ERAs, die für ein einzelnes Zeichen stehen
      Die folgenden ERAs ersetzen ein einzelnes Zeichen oder ein einzelnes
      Zeichen aus einer Ansammlung von Zeichen:

      Gewöhnliche Zeichen
      Ein gewöhnliches Zeichen ist ein ERA, der für sich selbst steht.

      Spezialzeichen
      Die hier geltenden Spezialzeichen und die Umgebungen,
      in denen sie Spezialbedeutung haben, sind:

      . [ \ ( ) * + ? $ |     Spezial, jedoch nicht innerhalb
                              einer Zeichenklasse ([...]).

      ^                       Spezial, jedoch nicht innerhalb einer
                              Zeichenklasse in nichtführender Position.

      begrenzer               Jedes Zeichen, das einen ERA begrenzt, ist
                              spezial für denjenigen ERA  (i.d.R. / und ?)

      Punkt

      Ein Punkt (.) außerhalb einer Zeichenklasse ersetzt ein beliebiges
      Zeichen außer NL.

    ERA Zeichenklasse
      Siehe RA Zeichenklasse

    ERAs, die mehrere Zeichen ersetzen
      Sie werden konstruiert aus ERAs, die ein Zeichen ersetzen.

      Im Unterschied zu RAs können bei den ERAs mehrere hintereinander
      stehende ERAs mittels Klammern () zu einer Einheit zusammengefaßt
      werden, so daß Spezialzeichen auf die gesamte Einheit wirken.
      Eine solche Einheit kann dann als einzelnes Zeichen aufgefaßt werden.
      Die Klammern zeigen lediglich an, ob und was zusammengefaßt werden soll
      und sind nach Erfüllung ihrer Aufgabe nicht mehr Bestandteil eines ERA.

        ERAERA      Beispielsweise  bc  paßt zum ersten Vorkommen von  bc
                    in  abcdefabcdef:  zweites und drittes Zeichen.
                    Gleiches gilt für bc in Klammern:  (bc)
                    Ein ERA sucht generell Übereinstimmung mit der
                    ersten und längstmöglichen Zeichenfolge.

        ERA+        Paßt zu einem oder mehr Vorkommen von ERA.
                    b+c  paßt zum vierten bis siebten Zeichen in
                    acabbbcde  .

        ERA*        Paßt zu null oder mehr Vorkommen von ERA.
                    b*c  paßt zum ersten Zeichen in
                    cabbbcde  .
                    b*cd  paßt zum dritten bis siebten Zeichen in
                    cabbbcdebbbbbbcdbc  .

        ERA?        Paßt zu null oder einem Vorkommen von ERA.
                    b?c  paßt zum zweiten Zeichen in
                    acabbbcde  .

    Alternative
      Zwei ERAs mit dem Zeichen  |  dazwischen passen zu einem Vergleichs=
      muster, daß zu dem einen oder dem anderen ERA paßt.
      Der ERA
      ((ab)|c)d  paßt zu
      abd        oder zu
      cd

    Vorrang
      Mit fallender Priorität:

           [ ]            Zeichenklasse
           * + ?          Stern, Pluszeichen, Fragezeichen
           ^ $            Positionsfixierung
                          Verkettung, Hintereinanderfolge
           |              Oder-Auswahl, Alternative

      Bei  abba|cde  sucht der ERA Übereinstimmung mit  abba  oder mit  cde
      weil Verkettung eine höhere Priorität hat als die Alternative.

    Positionsfixierung eines ERA
      Siehe Positionsfixierung eines RA  ( ^  $ )



 ZEICHENMUSTERVERGLEICH  (pattern matching notation)

    Patterns, die für ein einzelnes Zeichen stehen
      Die folgenden Patterns ersetzen ein einzelnes Zeichen oder
      ein einzelnes Zeichen aus einer Ansammlung von Zeichen:

      Gewöhnliche Zeichen
      Ein gewöhnliches Zeichen ist ein Pattern, das für sich selbst steht.
      Die Spezialzeichenfolgen der RAs  \( \) \{ \} \1 bis \9
      gelten hier nicht.

      Spezialzeichen
      Spezialzeichen haben eine Spezialbedeutung innerhalb von Patterns,
      das heißt, sie enthalten eine bestimmte Funktionalität.
      Ein vorangestellter Backslash hebt die Spezialbedeutung eines Zeichens
      auf - das Zeichen steht dann für sich selbst.
      Diese Spezialzeichen und die Umgebungen, in denen sie Spezialbedeutung
      haben, sind:

           ? * [          Spezial, jedoch nicht innerhalb einer
                          Zeichenklasse ([...])

      Fragezeichen

      Ein Fragezeichen (?) außerhalb einer Zeichenklasse
      steht für ein beliebiges Zeichen.  (Bei RAs und ERAs der Punkt (.))

    Zeichenklasse
      Siehe RA Zeichenklasse.
      Abweichungen:

           Das Ausrufezeichen (!) ersetzt das Zeichen  ^  in seiner Funktion
           als Invertierer.

           Der Backslash (\) wird innerhalb als Maskierzeichen benutzt,
           das Spezialbedeutungen aufhebt.

    Patterns, die mehrere Zeichen ersetzen
      Sie werden konstruiert aus Patterns, die ein Zeichen ersetzen.

        *           Der Stern paßt zu jeder Zeichenkette, einschließlich
                    der leeren Zeichenkette.
                    Es werden beliebig viele beliebige Zeichen ersetzt.
                    Der Stern ist hier das, was bei den RAs und ERAs
                    die Zeichenfolge  .*  ist. Dort werden werden durch
                    den Stern beliebig viele bestimmte Zeichen ersetzt.

        RARA        a[bc]  paßt zu          (Verkettung)
                    ab     und zu
                    ac

                    a*d   paßt zu
                    ad    ,
                    abd   ,
                    abcd  , jedoch nicht zu  abc .

                    *a*d*
                    paßt zu einem Muster, das irgendwo ein  a  enthält,
                    dem in beliebigem Abstand ein  d  folgt...



 SIEHE AUCH
      bish(K), expr(K), grep(K), pg(K).

 AUTOR
      Helmut Schellong, Bad Salzuflen

 LITERATUR
      Manual-Page  regexp(5)
      HP-UX Rel. 9.0  -  Hewlett-Packard Company



^

 ansi®                                                                ansi®



 NAME
      ansi-Treiber-Funktionen bei Ausgaben auf den Bildschirm
      (Intern, nur bei bsh32.exe)

 SYNTAX
      Escape-Sequenzen:  esc[Z, esc[nZ, esc[n;n...m, esc[=nZ, ...



 BESCHREIBUNG
      Mit Hilfe von Escape-Sequenzen können verschiedene Funktionen
      des Bildschirms -und auch andere- gesteuert werden.

      Eine Escape-Sequenz beginnt stets mit einem Escape-Zeichen
      (dezimal 27), fast immer gefolgt von dem Zeichen '['.
      Beendet wird solch eine spezielle Zeichenfolge fast
      ausnahmslos durch einen Buchstaben, meist ein Großbuchstabe.

      Escape-Sequenzen werden nur verarbeitet, wenn sie zu einem
      Bildschirm-Gerät geschrieben werden.
      Das sind beispielsweise:
      CON, CONOUT$, /dev/tty, /dev/tty01, /dev/console, ...

      Ein 'Leckerbissen' ist die MultiScreen-Sequenz esc[nz, s.u.

      Mit  esc[c;sp  können Tasten programmiert werden, wodurch
      man sich eine _sehr_ bequeme Bedienung zurechtbasteln kann.


      Sequenzen gemäß ANSI X3.64-1979:
      --------------------------------
      Für ein fehlendes 'n' wird in der Regel '1' eingesetzt.

         esc[nA        Cursor n Zeilen aufwärts
         esc[nB        Cursor n Zeilen abwärts
         esc[nC        Cursor n Zeichen vorwärts
         esc[nD        Cursor n Zeichen zurück
         esc[nE        Cursor auf Anfang, n Zeilen abwärts
         esc[nF        Cursor auf Anfang, n Zeilen aufwärts
         esc[H         Cursor auf Position 1;1
         esc[v;hH      Cursor auf Position vertikal;horizontal
         esc[v;hf      dito
         esc[n`        Cursor auf Spalte n  (`==Backquote!)
         esc[nG        Cursor auf Spalte n-1  (nicht ANSI)
         esc[nd        Cursor auf Zeile n
         esc[nP        Löscht n Zeichen
         esc[nM        Löscht n Zeilen
         esc[nX        Überschreibt n Zeichen leer
         esc[0J        Löscht Bildschirm, von Position bis Ende
             1J        Löscht Bildschirm, von Anfang bis Position
             2J        Löscht Bildschirm, Cursor auf 1;1
             3J        Löscht Bildschirmpuffer, Cursor 1;1 (n.ANSI)
         esc[K         Löscht Zeile, von Position bis Ende
         esc[0K        Löscht Zeile, von Position bis Ende
             1K        Löscht Zeile, von Anfang bis Position
             2K        Löscht Zeile
         esc[n@        Einfügt n Leerstellen
         esc[nL        Einfügt n Leerzeilen
         esc[nS        Scrollt Bild n Zeilen aufwärts
         esc[nT        Scrollt Bild n Zeilen abwärts
         esc[nZ     -- Cursor n TABs zurück
         esc[s         Sichert aktuelle Cursor-Position (Wert=0)
         esc[u         Holt Cursor-Position             (Wert=0)
         esc[ns        Sichert aktuelle Cursor-Pos. (16 Werte, n=0-15)
         esc[nu        Holt Cursor-Position         (16 Werte, n=0-15)
         esc[a;ns      Sichert aktuelle Zeichenattribute (n=0-15)
                       a=0: normal+reverse
                       a=1: normal
                       a=2: reverse
         esc[a;nu      Holt aktuelle Zeichenattribute    (n=0-15)
                       a=0: aktuelle Mode (7m,0m) entscheidet.
                       a=1: normal
                       a=2: reverse
         esc[?25h      Cursor sichtbar
         esc[?25l      Cursor unsichtbar
         esc[?6l       Normaler Cursor-Modus (?) (Home)
         esc[nm        Setzt Zeichenattribute:
                       (mehrere:  esc[n1;n2;n3;n4...m  sind angebbar)
         esc[0m        Löscht Zeichenattribute: 1m,7m,8m
             1m        Helligkeit ein
             2m      - Helligkeit gering
             3m      - Italic ein
             4m      - Unterstreichen ein
             5m        Blinken ein
             6m      - Blinken ein, hohe Frequenz
             7m        Reverse video ein
             8m        Sichtbarkeit (Input-Echo) aus.
                       Wirkt nicht innerhalb der Kommandozeile des
                       Kommandozeilen-Editors; ist dennoch aktiviert.
            10m      - Primärer Font
            11m      - Erster alternativer Font
            12m      - Zweiter alternativer Font
            19m      - Neunter alternativer Font
            21m      - Helligkeit aus
            22m        Normal-Farbe oder -Helligkeit
            23m      - Italic aus
            24m      - Unterstreichen aus
            25m        Blinken aus
            27m        Reverse video aus
            30m        Vordergrund schwarz
            31m        Vordergrund rot
            32m        Vordergrund grün
            33m        Vordergrund braun
            34m        Vordergrund blau
            35m        Vordergrund magenta
            36m        Vordergrund cyan
            37m        Vordergrund weiß
            38m        Erweiterte Vordergrundfarbe
		       esc[38;5;Cm        C=0..255; s.u.
                       esc[38;2;r;g;bm    rgb=0..255
            39m        Default Fordergrund
            40m        Hintergrund schwarz
            41m        Hintergrund rot
            42m        Hintergrund grün
            43m        Hintergrund braun
            44m        Hintergrund blau
            45m        Hintergrund magenta
            46m        Hintergrund cyan
            47m        Hintergrund weiß
            48m        Erweiterte Hintergrundfarbe
		       esc[48;5;Cm        C=0..255; s.u.
                       esc[48;2;r;g;bm    rgb=0..255
            49m        Default Hintergrund
             90.. 97m  Helle Vordergrundfarbe
            100..107m  Helle Hintergrundfarbe
         esc[6n        Schreibt die aktuelle Cursor-Position
                       in die Eingabe:  "VP HP\n"
         esc[2i        Konvertiert den Bildschirmpuffer und
                       schreibt diese Daten (OEMTEXT) in die Zwischenablage.
         esc[2h     -- Locks keyboard
         esc[2l     -- Unlocks keyboard
         esc[=7h       Autowrap ein
         esc[=7l       Autowrap aus
         esc[c;sp      Programmiert Tasten:
                          code;string[;...;...]p
                          string;code
                          code;code
                          string;string
                       Siehe unten: HINWEISE.
         38m, 48m:
          0- 7:  Normalhelle Farben
          8-15:  Helle Farben
         16-E7:  6 * 6 * 6 = 216 colors: 16 + 36 * r + 6 * g + b (0 <= r, g, b <= 5)
         E8-FF:  grayscale from black to white in 24 steps


      Sequenzen nicht ANSI-konform:
      -----------------------------
         esc[=cA    -- Overscan-Farbe auf c
         esc[=f;dB     Signalton  freq;dauer  37-32kHz;millisek
                       (f;d  werden nur unter NT berücksichtigt)
         esc[=s;eC     Cursor-Größe  start;ende (0;15,...,16;0)
                       Bei s>e oder s>15 wird Cursor unsichtbar.
                       (0;13 hat gleiche Wirkung wie 2;15 ,
                        da Windows nur *einen* Wert (1-100) verarbeitet.)
         esc[=0C       Schreibt aktuelle start;ende-Werte in die Eingabe.
                       Siehe unten: esc[=nM
         escQFn"str"-- Programmiert die Funktionstaste Fn mit "str"
                       Abgrenzungen ": irgendwelche Zeichen nicht in str
                       F1:Fn=='0', F2:Fn=='1', ..., F16:Fn=='?', ...,
                       bis F96:
         esc[0k        Tastendruck-Klick ein
                       (Wirkt nur unter NT richtig.)
         esc[1k        Tastendruck-Klick aus
         esc[nz        MultiScreen: Wechselt zu Bildschirm n
         esc[=cF       Normale Vordergrundfarbe auf c
         esc[=cG       Normale Hintergrundfarbe auf c
         esc[=cH       Reverse Vordergrundfarbe auf c
         esc[=cI       Reverse Hintergrundfarbe auf c
         esc[=cJ    -- Grafik Vordergrundfarbe auf c
         esc[=cK    -- Grafik Hintergrundfarbe auf c
         esc[=0L       Füllung neuer Bereiche mit aktuellen Farben (STD)
              1L       Füllung neuer Bereiche mit Normal-Farben
         esc[=0M       Schreibt aktuelle Normal-Farben in die Eingabe
              1M       Schreibt aktuelle Reverse-Farben in die Eingabe
              2M    -- Schreibt aktuelle Grafik-Farben in die Eingabe:
                       Rückgabe:  "VG HG\n", als dezimale Digit-Strings.
                       Siehe BEISPIELE.

         Farbwerte:
         0   Schwarz      8   Grau
         1   Blau         9   Hell Blau
         2   Grün        10   Hell Grün
         3   Cyan        11   Hell Cyan
         4   Rot         12   Hell Rot
         5   Magenta     13   Hell Magenta
         6   Braun       14   Gelb
         7   Weiß        15   Hell Weiß



 HINWEISE
      bsh:  set +S / set -S  schalten ansi aus/ein.

      readc.com  funktioniert auch unter NT.

      Normal- und Reverse-Farben sind voneinander getrennt.
      Ebenso die nm- von den =cX-Farb-Einstellungen.
      7m / 0m  schalten Reverse ein/aus.
      =cF =cG =cH =cI  gestatten eine getrennte Einstellung,
      zudem mit Werten von 0-15, also einschließlich bold-Bit.
      Man beachte, daß eine Reverse-Farbwahl im Normal-Modus
      keine sofortige Wirkung zeigt, sondern erst bei esc[7m !

      Die Zeichenfolgen - und -- (siehe oben) bedeuten, daß
      diese Escape-Sequenzen nicht (--) oder eventuell (-)
      realisiert wurden/werden.

      Der interne Kommandozeilen-Editor der bsh32 hat (ebenfalls)
      ein Tasten-Mapping eingebaut:  <Alt>+<Taste>
      Mit Escape-Sequenzen programmierte Tasten wirken nur
      bei eingeschaltetem Kommandozeilen-Editor (set -E).

      Die Sequenz 8m ist zur Eingabe von Geheimworten
      nützlich.
      Wirkt nicht sichtbar innerhalb der Kommandozeile des
      Kommandozeilen-Editors, ist aber dennoch aktiv.
      Wirkt aber beim read-Kommando, usw.

      Tasten-Mapping mit  esc[...p:
      =============================
           echo '%e["sf9";"echo 999 "p%c'
      programmiert 'echo 999 ' auf die Tasten <Shift>+<F9>.
      Nach Tastendruck sieht die Kommandozeile so aus:
           #  echo 999 _
      und man kann <Enter> drücken zur Ausführung.

           echo '%e["sf9";"echo 999%r"p%c'
      programmiert die <Enter>-Taste gleich mit (%r==CR).

           echo '%e["scaf12";"echo aaa%r"p%c'
           echo '%e["sca;f12";"echo aaa%r"p%c'
           echo '%e["sca:f12";"echo aaa%r"p%c'
      <Shift>+<Ctrl>+<Alt>+<F12>, die 96-ste Fu-Taste.

      Wie oben in der Liste gezeigt, können Strings
      und Dezimalzahlen beliebig kombiniert werden.
      Mit Zahlen ist immer nur _ein_ Zeichen darstellbar:

           echo '%e[65;66;"B";67;"C";68p'
           echo '%e["aA";"B";"a:B";"a:C";"C";"D"p'

      <Alt>+<A>==B, <Alt>+<B>==C, <Alt>+<C>==D
      Man beachte das <Alt>:
      Bei der Programmierung von normalen Einzelzeichen
      ist nur <Alt>+<Zeichen> oder <Alt>+<Shift>+<Zeichen>
      möglich, auch wenn man es bei Zahlenangabe anstelle
      von Strings nicht angeben konnte.

      Es sind maximal 8 Paare innerhalb einer einzigen
      Sequenz  esc[...p  angebbar.

      Anstelle von  "aa'a'aa"  kann auch  'aa"a"aa'  verwendet
      werden, damit man die Abgrenzungszeichen ('") auch
      jeweils programmieren kann:
           Die Ergebnisse:   aa'a'aa   und   aa"a"aa
      Noch universeller ist es, zwei Delimiter innerhalb
      direkt hintereinander zu stellen:
           "aa""bb"  programmiert:  aa"bb
           'aa''bb'  programmiert:  aa'bb
           'aa''""'  programmiert:  aa'""
           'aa''"'   programmiert:  aa'"
           ''''      programmiert:  '
           '''       programmiert:  FEHLER!
           ""        programmiert:  LEER
           ''        programmiert:  LEER

           echo '%e["sca:f12";"echo ""aaa  b""%r"p%c'
      programmiert:
           echo "aaa  b"CR

      MultiScreen:
           echo '%e["sf4";"echo ''%%e[4z%%c''%r"p%c'
      programmiert:
           echo '%e[4z%c'CR
      womit man durch <Shift>+<F4> zum Screen4 wechselt.

      Maskierungen:
           echo '%e["sf4";"echo ''%%e[4z%%c''%r"p%c'
                '                                  '
                                ''         ''
           für die Shell:  '' --> '
                                  %%    %%
           für das äußere echo-Kommando:  %% --> %
           %c  unterdrückt Zeilenvorschub.
           %e  ist Kurzform von  %033.
      Solche Maskierebenen sind leider notwendig, wenn
      man alles machen können will.
      Besser so als gar nicht.
      Hier sind immerhin drei Syntax-Formen verschachtelt
      beteiligt:  Shell (bsh), echo-Kommando und ansi-Treiber!
      Aber in der Praxis braucht man nur _ein_ erfolgreiches
      Muster, das man ja kopieren kann.
      Weiterhin können Shell-Variablen benutzt werden:
           E="xyz"; echo "...$E..."; ...
      Das macht's dann doch wieder einfach, weil hübsch
      nacheinander und weil  $E  vieles verbirgt.



 BEISPIELE
      Umgang mit den Input-Schreib-Sequenzen 6n =0C =0M =1M:

           echo '%033[=0M%c'; read vordgr hintgr
           echo '%e[=0M%c'; read vordgr hintgr
           echo '%e[=0M%e[8m%c'; read vordgr hintgr; echo '%e[0m%c'

      Auf diese Weise verhindert man, daß die Informationen
      direkt als Eingabe von Kommandos verarbeitet werden;
      Ohne Zeilenvorschub müßte man bei 'read' <Enter> drücken.

      Das will man ja nicht haben:
           #  echo '%e[=0C%c'
           #  13 15
           bsh: Kommando nicht gefunden: '13'
           #  _

      Die Sequenzen 8m/0m schalten das Echo der Systemfunktion
      innerhalb von read aus/ein.
      Die beiden Zahlen werden auf diese Weise nicht sichtbar.



 EXIT-CODE
      Gibt es nicht.
      Bei falschen oder unbekannten Sequenzen werden diese
      teilweise ausgeschrieben, also nicht ganz 'geschluckt'.

 DIAGNOSE
      Es gibt Fehlermeldungen, falls dieser interne ansi-Treiber
      gar nicht genutzt werden kann.


 SIEHE AUCH
      bsh(K), readc(K), bsh32.exe, DOS-help:ansi.sys .

 AUTOR
      Diese Funktionen  ansi  wurden entwickelt von:
      Helmut Schellong, Bad Salzuflen



^

 readc(K)                                                              readc(K)



 NAME
      readc.com - Liest im raw-Modus ein Zeichen von der Tastatur


 SYNTAX
      readc  [ -cew2 ]
      keystr=`readc`



 BESCHREIBUNG
      Das Kommando  readc  wartet nach Aufruf auf einen Tastendruck
      oder eine Tastendruck-Kombination (<Taste>,<Ctrl>+<Taste>,...).
      Ist ein solcher erfolgt, schreibt das Kommando eine zur Taste
      gehörende Zeichenkette (Kürzel) oder das originale Einzelzeichen
      zur Standard-Ausgabe.
      Die Eingabetaste <Enter> braucht also nicht als Abschluß gedrückt
      zu werden, sondern für sie gibt es auch (ein) Kürzel.


      Die Kommandozeilen-Optionen sind:
      ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
      -c     Es werden alternative Kürzel für die Zeichen 1-31 ausgegeben:
                  ^A ... ^Z ^[ ... ^_
             Dies ist eine verbreitete Darstellungsart für <Ctrl>-Zeichen.

      -e     Aktiviert eine Echo-Funktion.
             Bei normaler Anwendung innerhalb eines geeigneten Shell-Programms
             werden die Kürzel und Einzelzeichen per Kommando-Substitution
             in eine Variable gelenkt:  key=`readc` ( oder key=$(readc) ).
             Option -e bewirkt, daß (nur!) Einzelzeichen dann zur Standard-
             -Fehlerausgabe geschrieben werden, damit sie sichtbar auf dem
             Bildschirm erscheinen und nicht nur in eine Variable gelangen.
             Ein Echo wird vorgenommen falls nur die Standard-Ausgabe oder
             nur die Standard-Fehlerausgabe mit dem Bildschirm verknüpft ist.
             Bei gesetzter Option -2 geht das Echo auf Handle 1 statt 2.

      -w     Alle Kürzel werden zur Standard-Ausgabe geschrieben,
             damit man sie kennenlernen kann.
             Zu diesem Zweck kann man sie per Umlenkung in eine geeignete
             Zieldatei schreiben:  readc -w >> script_datei
             Diese Option berücksichtigt gesetzte Optionen -c und -2.

      -2     Die Kürzel werden zur Standard-Fehlerausgabe geschrieben.
             Handle 2 wird also anstelle von Handle 1 verwendet.

      Die Kommandozeilen-Optionen können beliebig gruppiert angegeben werden.


      Die annähernd 200 Kürzel sind selbsterklärend und bestehen
      weit überwiegend nur aus Großbuchstaben und den Zeichen '_1234567890'.

      Beispiel:  ESC, INS, HOME, UP, DOWN, LEFT, RIGHT, F1, F11, BACK,
                 ENTER, C_ENTER, C_D, ^D, C_F1, A_F5, N5, A_N5, ...
         C_ ist <Ctrl>
         A_ ist <Alt>
         N  ist <auf dem Nummernblock>

      Eine Liste aller Kürzel kann man per '-w' leicht erzeugen.
      Wenn man 'readc' aufruft und eine Taste drückt, sieht man sofort
      die Antwort. In dieser Dokumentation ist daher keine Liste enthalten.

      Ein Zeilenvorschub wird nur bei nicht umgelenkter Ausgabe ausgegeben.
      Eine Garantie gibt es nicht dafür, daß sämtliche Kürzel auf jeder
      beliebigen Hardware zu den Tastendrücken passen.

      Dieses Kommando macht nur richtig Sinn in Zusammenarbeit mit einem
      Shell-Programm, das Kommando-Substitution beherrscht.
      In der Regel sind das die UNIX-Shells und 'bish.exe' für DOS.


      Umgebungsvariablen:
      ~~~~~~~~~~~~~~~~~~~
      readc berücksichtigt hier folgende Variablen (Environment):
      BSHAUTOR
        Um die Autoren-Meldung zu unterdrücken:
        BSHAUTOR=H.Schellong,Vlotho
      READCPROGRAM
        Um die Freeware-Meldung zu unterdrücken:
        READCPROGRAM=Freeware_nur_fuer_nichtgewerbliche_Verwendung
        (BSHAUTOR muß hierfür auch gesetzt sein.)



 BEISPIELE
      keystr=`readc`
      keystr=$(readc -ce)
      readc -wc > shorties
      readc


 SIEHE AUCH
      bish(K), read(bish(K))

 DIAGNOSE
      Fehlermeldungen mit nachfolgendem Programmabbruch.

 EXIT-CODE
      0     Kein Fehler aufgetreten.
      >0    Fehler


 AUTOR
      Das Programm  readc  wurde entwickelt von:
      Helmut Schellong, Bad Salzuflen
      Copyright © 1997



^

 calc(K)                                                                calc(K)



 NAME
      calc.exe - Rechnet mit Gleit- und Festkommazahlen

 SYNTAX
      calc  [ arithmetischer_ausdruck ... ]
      kdo | calc
      calc < datei



 BESCHREIBUNG
      Das Kommando  calc  gestattet Berechnungen mit Gleitkommazahlen und
      Festkommazahlen.
      Es sind in etwa diejenigen Rechenoperationen und Funktionen vorhanden,
      die wissenschaftliche Taschenrechner zur Verfügung stellen.
      Zusätzlich gibt es Operationen, wie sie typischerweise bei
      Programmiersprachen anzufinden sind.

      calc  verarbeitet und produziert bei Eingabe und Ausgabe
      die Darstellungsarten  Dezimal, Hexadezimal, Octal und Dual.
      Die Darstellung bei Ausgabe ist einstellbar, bei Eingabe wird die
      Darstellung mittels der Suffixe  h,o,b  identifiziert,
      wobei bei Hexadezimaldarstellung gegebenenfalls eine Null (0)
      vorangestellt werden muß:  0fa98ch

      Ergebnisse werden zur Standard-Ausgabe geschrieben.
      Die Eingabe entnimmt calc angegebenen Argumenten, wobei nach Erreichen
      des Endes eines jeden Argumentes die Berechnung gestartet und
      ein zugehöriges Ergebnis (manchmal zwei oder drei) ausgegeben wird.
      Das bedeutet, daß jedes Argument ein sinnvoller arithmetischer Ausdruck
      sein muß.
      Die Ausgabe kann unterdrückt werden, durch Anhängen eines Leerzeichens
      als letztes Zeichen eines Argumentes.
      Falls keine Argumente angegeben wurden, liest calc von der
      Standard-Eingabe.
      Hierbei werden arithmetische Ausdrücke durch ein Semikolon (;),
      ein Newline-Zeichen (NL) oder Eingabeende beendet.
      Ein Leerzeichen zur Ausgabeunterdrückung muß vor den vorgenannten
      Endemarkierungen stehen.
      Wenn beim Lesen von der Standard-Eingabe diese mit einem Gerät
      (z.B. Tastatur) verknüpft ist, beendet ein ^D (Ctrl-D) am Zeilenanfang
      die Eingabe.

      calc  hat 26 interne Variablen  a,b,c,d,...,z .
      Definierte Inhalte bleiben während eines Aufrufs des Kommandos erhalten.
      Lesezugriff auf eine nichtgesetzte Variable ist ein Fehler.

      Bei Ganzzahloperationen wird (zwischendurch) mit 32 Bit gerechnet.
      Generell wird gleitkommamäßig operiert, und zwar mit mindestens
      15-stelliger Signifikanz, unter DOS 19-stellig, unter HPUX 15/31-stellig.


      calc berücksichtigt die folgenden Umgebungsvariablen (Environment):
      CALCAUTOR
        Um die Autoren-Meldung zu unterdrücken:
        CALCAUTOR=H.Schellong,Vlotho
      CALCPROGRAM
        Um die Freeware-Meldung zu unterdrücken:
        CALCPROGRAM=Freeware_nur_fuer_nichtgewerbliche_Verwendung
        (CALCAUTOR muß hierfür auch gesetzt sein.)


      Einstellungen und Kommandos:

        deg      Argumente in Grad bei sin, cos, tan, cot,
                 asin, acos, atan, acot, u.a. (default)
        rad      Argumente in Radiant
        dhob     Zahlendarstellung  dezimal, hexadezimal, oktal und bit.
                 Eingabe beliebig, jedoch mindestens 2 Buchstaben,
                 gegebenenfalls doppelt wie z.B. 'dd'.
                 Bei Eingabe gilt gleiche Darstellung wie bei Ausgabe.
        PI       Zeigen die Zahlen pi, e und w2 mit bis zu 99 Nachkommastellen.
        EU       (Dies sind lediglich Zeichenketten-Ausgaben.)
        QW


      Operatoren:

        dyadisch:    +  -  *  /  %  **  //  &  ^  |  <<  >>
        monadisch:   +  -  "  :  !  ~   #
        Klammern:    ()  []  {}  <>

        +            Addition  (unär = Absolutwert |x|)
        -            Subtraktion  (auch unär)
        *            Multiplikation
        /            Division
        %            Divisionsrest (modulo)
        "            Quadrat, (unär/monadisch)
        :            Quadratwurzel, (unär/monadisch)
        **           Potenzierung für GANZzahlige Exponenten (s.pow())
        //           N'te Wurzel aus x
        &            Binäre UND(AND)-Verknüpfung
        |            Binäre ODER(OR)-Verknüpfung
        ^            Binäre EXOR-Verknüpfung
        ~            Binäres NICHT(NOT), (unär)
        <<           Links-Schieben
        >>           Rechts-Schieben
        !            Fakultät, (unär)   (!6 = 1·2·3·4·5·6 = 720) (<=!1754)
        <{[()]}>     Klammern
        #c           liefert Zeichensatz-Wert des Zeichens 'c'
        ,            Komma  als Trenner bei >=2 Funktionsargumenten

        Der Vorrang der Operatoren entspricht üblichen Gepflogenheiten.
        Punkt- geht vor Strichrechnung, unäre Operatoren haben Vorrang
        vor dyadischen und werden von rechts nach links abgearbeitet.
        Ausnahme bildet die Zuweisung per '=' (siehe unten).

        Syntax / Beispiele:

        Es dürfen Leerzeichen, Tabs und NewLines eingefügt werden.
        (Stellenweise Spezialbedeutung der NL siehe oben.)
        Der Multiplikations-Operator '*' kann oft weggelassen werden:
        4(a+3)(66-18)f   entspricht   4*(a+3)*(66-18)*f
                a b 51   entspricht   a*b*51

        b=5
        d=b
        a= 3+12.68+(b-1)c( 11+pow(3,b=5*17)b )-32.4--d+!8
        a
        36
        nk(49,6) + b= 1100100b&~(1<<5)
        h=i=j=k= a b c :3 ""5 44.52



      Funktionen:

        y= pi()               y= eu()               y= sqrt(x)         
        y= sin(x)             y= cos(x)             y= tan(x)          
        y= cot(x)             y= asin(x)            y= acos(x)         
        y= atan(x)            y= acot(x)            y= sinh(x)         
        y= cosh(x)            y= tanh(x)            y= coth(x)         
        y= asinh(x)           y= acosh(x)           y= atanh(x)        
        y= acoth(x)           y= lg(x)              y= ln(x)           
        y= ld(x)              y= ilg(x)             y= iln(x)          
        y= ild(x)             y= abs(x)             y= rnd(x)          
        y= up(x)              y= dwn(x)            -y= chop(x)         
        y= ichop(x)           y= fak(x)            2y= xtract(x)       
       3y= dsm(x)             y= log(a,b)           y= pow(a,b)        
        y= powi(a,b)          y= root(a,b)          y= prem(a,b)       
       -y= scale(a,b)         y= nk(a,b)            y= zz(a,b)         
        y= rp(a,b)          -2y= ctop(a,b)        -2y= ptoc(a,b)       
      -3y= zze(a,b,c)       -2y= quaequ(a,b,c)      y= smd(a,b,c)      

        Bei 2 oder 3 Resultatwerten werden die Variablen u und v belegt.
        -)  Funktion nicht in jeder OS-Version vorhanden.


      Funktionsbeschreibungen:

            pi(0)  Liefert die Zahl PI
            eu(0)  Liefert die Eulersche Zahl e= iln(1)
          sqrt(1)  QuadratWurzel
           sin(1)  Sinus (Beachte rad/deg !)
           cos(1)  CoSinus
           tan(1)  Tangens
           cot(1)  CoTangens
          asin(1)  ArcusSinus (sin-Umkehrfunktion)
          acos(1)  ArcusCoSinus
          atan(1)  ArcusTangens
          acot(1)  ArcusCoTangens
          sinh(1)  SinusHyperbolicus
          cosh(1)  CoSinusHyperbolicus
          tanh(1)  TangensHyperbolicus
          coth(1)  CoTangensHyperbolicus
         asinh(1)  AreaSinusHyperbolicus (sinh-Umkehrfunktion)
         acosh(1)  AreaCoSinusHyperbolicus
         atanh(1)  AreaTangensHyperbolicus
         acoth(1)  AreaCoTangensHyperbolicus
            lg(1)  Dekadischer(Zehner-) Logarithmus, zur Basis 10
            ln(1)  Natürlicher Logarithmus, zur Basis e
            ld(1)  Logarithmus Dualis, zur Basis 2  (ld(16)=4; 2^4=16)
           ilg(1)  lg-Umkehrfunktion (z.B. ilg(2)=10²=100)
           iln(1)  ln-Umkehrfunktion
           ild(1)  ld-Umkehrfunktion
           abs(1)  Absolutwert |x|  (Ergebnis ist immer positiv)
           rnd(1)  Rundet zur nächstliegenden ganzen Zahl ab/auf
            up(1)  Rundet in Richtung +unendlich
           dwn(1)  Rundet in Richtung -unendlich
          chop(1)  Rundet in Richtung 0
         ichop(1)  Schneidet die Vorkommastellen ab
           fak(1)  Fakultät von 4= 1·2·3·4 = 24  (x<=170 / x<=1754)
        xtract(1)  Extrahiert Signif.u.Expon.:  s·(2)^n = (x);
           dsm(1)  Stunden,Minuten,Sekunden =  (Dezimalzeit)
           log(2)  Logarithmus, n= log(beliebige Basis b, y)
           pow(2)  Potenzierung y=bü  (log-Umkehrfunktion)
          powi(2)  Potenzierung für ganzzahlige Exponenten n
          root(2)  y= n-te Wurzel von x;   y= (x, n)
          prem(2)  Divisionsrest von q/d:  r= (q, d)
         scale(2)  y= s·2^n;   y= (s, n)
            nk(2)  n über k;  lotto= nk(49,6),  6 aus 49
            zz(2)  y= wurzel(a²+b²);  Hypotenuse, Betrag |Z| komplexe Zahl
            rp(2)  y= 1/(1/a+1/b);  z.B. Widerstände parallel
          ctop(2)  Kartesische Koordinaten zu Polaren:  r,pi= (x,y)
          ptoc(2)  Polare Koordinaten zu Kartesischen:  x,y = (r,pi)
           zze(3)  |Z|,a1,jb1 =  (a0, jb0, exponent);   (a+jb)^n
        quaequ(3)  x1,x2= (a,b,c);   Quadratische Gleichung
           smd(3)  Dezimalzeit = (Stunden, Minuten, Sekunden)



 BEISPIELE
      (siehe auch bish-Kommandosyntax.)

      calc  "a=12.7 "  "f=0.8 "  "4(a+3)(66-18)f"
           2411.52

      echo "b=5 ;c=d=b ;
            a= 3+12.68+(b-1)c[ 11+pow(3,b=5*17)b ]-32.4--d+!8 ;
            a" | calc
           6.10598274310663e+43
            (Zwei Semikoli sind hier redundant!)

      calc  dhob 36
           36   000000024h   00000000044o   00000000000000000000000000100100b

      calc  "nk(49,6) + b= 1100100b&~(1<<5)"  'h=i=j=k= 4 b 5 :3 ""5 44.52'
                   13983884
           65544266.6600214

      calc < arithmetik_datei



 LIMITS
      2048 Byte     Beim Lesen von der Standard-Eingabe.
       256 Byte     Arithmetischer Ausdruck.


 EXIT-CODE
      0     Letztes Resultat war ungleich Null (0.0).
      1     Letztes Resultat war gleich Null (0.0).
      2     Bei Fehlern.
      3     Bei Abbruch wegen SIGNAL.


 SIEHE AUCH
      bish(K).


 AUTOR
      Dieses Kommando  calc  wurde entwickelt von:
      Helmut Schellong, Bad Salzuflen



^

 comx(K)                                                                comx(K)



 UNIX-Variante (VBM)



 NAME
      com - Kommunikation über serielle Schnittstelle
      ext - Kommunikation über serielle Schnittstelle
      (intern bish(K))

 SYNTAX
      com  +[LBM#T#A#H#]  /dev/term/0{0|1|2|3}[m|h|s|t]
      com  -B#focicoD#iD#od#id#ot#it#iO#oO#o[#]i[#]  [ name ]
      com  -spH                                      [ name|handle ]
      com  -|+b[1|0]nnn
      com  -
      ext  (wie com)
      $.



 BESCHREIBUNG
      Die Kommandos  com/ext  lesen aus der Shell-Variablen 'name'
      und schreiben zur seriellen Schnittstelle
      und/oder lesen von der seriellen Schnittstelle und schreiben
      in die Variable 'name'.
      Die Anzahl geschriebener/gelesener Zeichen kann
      der Spezial-Shell-Variablen '$.' entnommen werden,
      bei gegebener Option o und/oder i (nicht ic oc it ot ...).

      Kommandozeilen-Optionen:
           +    Gerätedatei
                  Angegebenes Device wird geöffnet mit -B9600.
                  tty-Device-Namen sind system-spezifisch:
                  /dev/tty1A  /dev/term/01m  ...
           +LB  Gerätedatei
                  Bei 'L' und/oder 'B' wird CLOCAL gesetzt
                  bzw. O_NONBLOCK nicht gesetzt.
           +M#  Gerätedatei
                  uchar c_cc[VMIN]=#; wird gesetzt. (0)
           +T#  Gerätedatei
                  uchar c_cc[VTIME]=#; wird gesetzt. (0)
                  1 entspricht 0.1 sec.
           +A#  Gerätedatei
                  Assoziation Controlling Terminal
                  (Falls O_NOCTTY fehlt)
                  ioctl(fd, TIOCNOTTY, 0|1);
           +H#    Angabe eines Handle.
                  open() wird nicht verwendet.

           -      Zuvor geöffnetes Device wird geschlossen.

           -s     Ausgabe des Status (7 Bits):
                     "bbbbbbb rts,cts,dtr,dsr,cd,ri,le"
                  Ausgabe zur Standard-Ausgabe, falls kein 'name'
                  angegeben ist, andernfalls Ausgabe in 'name'
                  oder zum angegebenen Handle.
                  tty-Ausgabe mit "rts,cts,...\n".
                  Hiernach sofortiger Exit! (TRUE)

           -p     PEEK: ist ein Eingabezeichen lesbar vorhanden?
                  Falls ja: Ausgabe zum angegebenen Handle oder
                  Ausgabe in 'name'.  (Binärmodus)
                  Variablenlänge==1 ggf. danach.
                  Ohne Argument verbleibt der Exit-Code.
                  Ein gelesenes Zeichen verbleibt lesbar im Puffer.
                  Hiernach sofortiger Exit!
                  Exit: TRUE/FALSE (0/1)

           -H     Ausgabe des Handle.
                  Hiernach sofortiger Exit!

           -B#    Einstellung der Schnittstellengeschwindigkeit (baud):
                     9600 19200 38400 57600 115200
                     4800  2400  1800  1200    600
                      300    50    75     0
                      110   134   150   200

           -f     FLASH: Ausgabe-Puffer wird ausgeschrieben.
                  Wartet auf Komplettierung!   tcdrain(fd)

           -oc    Ausgabepuffer löschen (clear).
           -ic    Eingabepuffer löschen (clear).
           -c     Beide Puffer löschen. (c ohne [oi] davor)
           -D#    Delay  (ohne o|i davor)
           -oD#   Ausgabe-Delay nach write()<=0 (-oD10)
           -iD#   Eingabe-Delay nach  read()<=0 (-iD10)
           -od#   Ausgabe-Delay nach Fehlendem  (-od10)
           -id#   Eingabe-Delay nach Fehlendem  (-id10)
           -ot#   Ausgabe-Timeout (-ot0)
           -it#   Eingabe-Timeout (-it0)
                  (Alle Zeiten in ms.
                   Granularität meistens 10ms.
                   Kleinere Werte werden meist aufgerundet.)

           -oO#   Setzt den o-Offset in der io-Variable.
           -iO#   Setzt den i-Offset in der io-Variable.
           -O#    Setzt beide Offsets. (ohne o|i davor)
                  (Voreingestellt ist 0)

           -o#    Ausgabe von maximal # Bytes.
           -i#    Eingabe von maximal # Bytes.
                  Ohne Zahlen # wird 2^31-1 angenommen.

           -bnnn  nnn= rts|cts|dtr|dsr|cd|ri|le
                  Testet, ob angegebenes Bit gesetzt ist.
                  Antwortet mit einem entsprechenden Exit-Code.
                  Hiernach sofortiger Exit!

           +b[1|0]nnn
                  Setzt ein angegebenes Bit auf 1 oder 0. (set/clear)
                  Ohne [1|0] wird 1 (set) angenommen.
                  Hiernach sofortiger Exit!
                  Exit=TRUE, wenn kein Fehler.

      Die Optionen können (prinzipiell) in beliebiger Kombination
      und Reihenfolge mittels eines(!) Argumentes angegeben werden.
      Die Reihenfolge wird aktionsmäßig berücksichtigt,
      allerdings bei gleichzeitig -oi gilt immer: o, dann i.
      Optionen nach -spb sind sinnlos, wegen jeweiligem
      sofortigen Exit.
      Bei mehreren Optionen ist die Herkunft eines eventuellen
      FALSE-Exit nicht feststellbar.

      Als Fehlendes wird gewertet, wenn die angegebene Byte-Anzahl
      nicht mit einem einzigen read()/write() 'erledigt' werden konnte.
      Es wird dann -d# ms gewartet und erneut versucht,
      bis  d#-Summe > t# .


      Der Maximal-Wert bei -o# wird auf die Inhaltslänge
      der Variable 'name' gesetzt, falls diese geringer ist.

      Maximal-Wert bei -i# :
      Ein bereits existierender Variableninhalt wird mit
      maximal # Bytes überschrieben, falls dieser Inhalt
      größer/gleich # oder größer/gleich 8*1024 Byte ist.
      Die bestehende Inhaltslänge wird nicht verändert.
      Andernfalls wird der Puffer dieses Kommandos (8*1024 Byte)
      verwendet, um eine Variable zu erzeugen oder deren Inhalt
      zu verlängern - bis maximal 8*1024 Byte.
      Variablen können viel größer sein als 8*1024 Byte.

      Bei gleichzeitiger Angabe von o und i
      kann mit einem einzelnen Kommando-Aufruf geschrieben
      und danach gelesen werden.
      In $. steht dann jedoch die abschließende i-Anzahl,
      während die o-Anzahl verloren ist.

      Achtung!: $. wird von 'conv' und 'cmpv' ebenfalls gesetzt,
      und hat den Startwert -1 .



 BEISPIEL
      extinp="@EEDATA:"
      ext  -B9600cit2500id20oi  extinp
      echo $extinp
      nread=$.


 EXIT-CODE
      0     falls nicht anders angegeben
      1     bei Fehler/Fehlschlag/FALSE-Situation


 AUTOR
      Dieses Kommando  comx  wurde entwickelt von:
      Helmut Schellong, Bad Salzuflen
      Copyright © 2002  CIE Convertronic GmbH, Kirchlengern
      Copyright © 2002  Helmut Schellong, Bad Salzuflen


 ------------------------------------------------------------------------------
 Variante: DOS 16Bit (Beck@IPC)


 NAME
      com - Kommunikation über serielle Schnittstelle 'com'
      ext - Kommunikation über serielle Schnittstelle 'ext'
      (intern bish(K))
      bish-Portierung für Embedded-DOS IPC@CHIP(Fa.Beck)

 SYNTAX
      com  -spb#h[#]focicod#id#ot#it#oT#iT#o[#]i[#]  [ name ]
      com
      com  -
      ext  (siehe oben)
      ext
      ext  -
      $.



 BESCHREIBUNG
      Die Kommandos  com/ext  lesen aus der Shell-Variablen 'name'
      und schreiben zur seriellen Schnittstelle
      und/oder lesen von der seriellen Schnittstelle und schreiben
      in die Variable 'name'.
      Die Anzahl geschriebener/gelesener Zeichen können
      der Spezial-Shell-Variablen '$.' entnommen werden,
      bei gegebener Option o und/oder i (nicht ic oc it ot ...).

      Kommandozeilen-Optionen:
           -s     Ausgabe des Status bbbbbbb (7 Bits: 6543210)
                     6     Ausgabepuffer leer
                     5     Ausgabepuffer nicht voll
                     4     Line-Break empfangen
                     3     Frame-Fehler
                     2     Parity-Fehler
                     1     Overrun Eingabepuffer
                     0     Eingabepuffer nicht leer
                  Ausgabe zur Standard-Ausgabe, falls kein 'name'
                  angegeben ist, andernfalls Ausgabe in 'name'.
                  (Textmodus)
                  Hiernach sofortiger Exit! (TRUE)

           -p     PEEK: ist ein Eingabezeichen lesbar vorhanden?
                  Falls ja: Ausgabe zur Standard-Ausgabe, falls kein 'name'
                  angegeben ist, andernfalls Ausgabe in 'name'.
                  (Binärmodus)
                  Ein gelesenes Zeichen verbleibt lesbar im Puffer.
                  Hiernach sofortiger Exit!
                  Exit: TRUE/FALSE

           -b#    Einstellung der Schnittstellengeschwindigkeit (baud):
                     b3840  (38400)
                     b19200
                     b9600
                     b4800
                     b2400
                     b1200
                     b600
                     b300
                  Danach sollte man mit ic und oc die Puffer löschen.

           -h     Hardware-Handshake (rts/cts) EIN
           -h1    Hardware-Handshake (rts/cts) EIN
           -h0    Hardware-Handshake (rts/cts) AUS
           -f     FLASH: Ausgabe-Puffer wird ausgeschrieben.
                  Wartet auf Komplettierung!
           -oc    Ausgabepuffer löschen (clear).
           -ic    Eingabepuffer löschen (clear).
           -od#   Ausgabe-Delay nach Zeichenfehlschlag d0..32767
           -id#   Eingabe-Delay nach Zeichenfehlschlag d0..32767
           -ot#   Ausgabe-Timeout t0..32767 ab 2. Fehlschlag
           -it#   Eingabe-Timeout t0..32767 ab 2. Fehlschlag
           -oT#   Ausgabe-Timeout T0..32767 Gesamt-Delay
           -iT#   Eingabe-Timeout T0..32767 Gesamt-Delay
                  (Alle Zeiten in ms)

           -o#    Ausgabe von maximal # Bytes.
           -i#    Eingabe von maximal # Bytes.
                  Ohne Zahlen # wird 32767 angenommen.

      Die Optionen können in beliebiger Kombination und Reihenfolge
      mittels eines(!) Argumentes angegeben werden.
      Die Reihenfolge wird aktionsmäßig berücksichtigt,
      allerdings bei gleichzeitig -oi gilt immer: o, dann i.
      Optionen nach -s oder -p sind sinnlos, wegen jeweiligem
      sofortigen Exit.


      Bei jeglicher erster Verwendung wird die Schnittstelle
      initialisiert. Beispielsweise bei 'com'.
      Bei Init-Erfolg wird Exit=0 (TRUE) gegeben.
      Explizite Deinitialisierung erfolgt durch 'com -'.
      Falls eine Schnittstelle STDIN/STDOUT zugeordnet ist,
      ist das nach Init nicht mehr der Fall, aber wieder
      nach De-Init.
      Die bish macht vor ihrem Exit automatisch De-Init.
      Nur eine Task kann eine Schnittstelle 'besitzen'.


      Der Maximal-Wert bei -o# wird auf die Inhaltslänge
      der Variable 'name' gesetzt, falls diese geringer ist.

      Maximal-Wert bei -i# :
      Ein bereits existierender Variableninhalt wird mit
      maximal # Bytes überschrieben, falls dieser Inhalt
      größer/gleich # oder größer/gleich 1024 Byte ist.
      Die bestehende Inhaltslänge wird nicht verändert.
      Andernfalls wird der Puffer dieses Kommandos (1024 Byte)
      verwendet, um eine Variable zu erzeugen oder deren Inhalt
      zu verlängern - bis maximal 1024 Byte.
      Variablen können sehr viel größer sein als 1024 Byte.

      Bei gleichzeitiger Angabe von o und i
      kann mit einem einzelnen Kommando-Aufruf geschrieben
      und danach gelesen werden.
      In $. steht dann jedoch die abschließende i-Anzahl,
      während die o-Anzahl verloren ist.

      Achtung!: $. wird von 'conv' und 'cmpv' ebenfalls gesetzt,
      und hat den Startwert -1 .



 BEISPIEL
      extinp="@DK40:"
      ext  -b9600icocit2000id10oi  extinp
      echo $extinp
      nread=$.


 EXIT-CODE
      0     falls nicht anders angegeben
      1     bei Fehler/Fehlschlag/FALSE-Situation


 AUTOR
      Dieses Kommando  comx  wurde entwickelt von:
      Helmut Schellong, Bad Salzuflen
      Copyright © 2001  CIE Convertronic GmbH, Kirchlengern
      Copyright © 2001  Helmut Schellong, Bad Salzuflen



^

 dat(K)                                                                  dat(K)



 NAME
      dat.exe - Setzt oder zeigt System-Datum und -Uhrzeit

 SYNTAX
      dat  [ TTMMJJhhmmss ]



 BESCHREIBUNG
      Das Kommando  dat (date_and_time)  setzt die Systemzeit
      oder zeigt sie an.
      Wenn kein Argument angegeben wurde, wird die aktuelle Systemzeit
      zur Standard-Ausgabe geschrieben.
      Das Ausgabe-Format ist mit dem oben gezeigten Eingabe-Format
      identisch.

      Bedeutung der Buchstaben in der Zeitangabe:
           Tag, Monat, Jahr, hour(Stunde), minute, sekunde.
      Es müssen gegebenenfalls führende Nullen (0) angegeben werden.

      Als Jahreszahl können Werte von  00 bis 99  angegeben werden.
      Daraus resultieren die Jahre 1980 bis 2079.
      (80...99 --> 1980...1999  und  00...79 --> 2000...2079)

      Bei der Ausgabe wird auf volle Sekunden aufgerundet.

      dat  berücksichtigt die folgenden Umgebungsvariablen (Environment):
      BSHAUTOR
        Um die Autoren-Meldung zu unterdrücken:
        BSHAUTOR=H.Schellong,Vlotho
      DATPROGRAM
        Um die Freeware-Meldung zu unterdrücken:
        DATPROGRAM=Freeware_nur_fuer_nichtgewerbliche_Verwendung
        (BSHAUTOR muß hierfür auch gesetzt sein.)



 BEISPIELE
      dat  011194223344
      Setzt die Systemzeit auf 01.11.1994, 22:33:44 Uhr.

      dat
      Zeigt die aktuelle Systemzeit.

      ADT=`dat`
      dat  011194223344
         ...
      dat  $ADT
      Setzt die Systemzeit vorübergehend auf einen bestimmten Wert.
      Die Aktion (...) sollte nicht zu lange dauern. (Wer zu spät kommt ...)


 EXIT-CODE
      0     Kein Fehler.
      1     Fehler bei den Optionen.


 SIEHE AUCH
      bish(K), touch(K).


 AUTOR
      Das Kommando  dat  wurde entwickelt von:
      Helmut Schellong, Bad Salzuflen



^

 dd(K)                                                                    dd(K)



 NAME
      dd.exe - Liest und schreibt Daten blockweise ein/aus


 SYNTAX
      dd  [if=idatei] [of=odatei]  [bs=n] [ibs=n] [obs=n]
          [count=n] [skip=n | iseek=n] [seek=n | oseek=n]
          [bmode=n] [ibmode=n] [obmode=n]
          [conv=bmode] [conv=notrunc] [noinfo]

      dd  [ if={h|f}d{0-3}:[c#h#s#] ]  [ of={h|f}d{0-3}:[c#h#s#] ]   [s.o.]

      dd  calc=n

      n:  #[{b|k|w|l}][{x|+}#[{b|k|w|l}]]...[{x|+|-}#[{b|k|w|l}]]
      #:  [0]...{1-9}...[{0-9}]...



 BESCHREIBUNG
      Das Kommando  dd  liest blockweise aus einer Eingabedatei und
      schreibt blockweise in eine Ausgabedatei.
      Die Blockgrößen können unabhängig voneinander eingestellt werden.
      Voreingestellt als Eingabe- und Ausgabedatei sind die Standard-
      -Eingabe und die Standard-Ausgabe.
      Geräte, wie Festplatten und Diskettenlaufwerke, können ebenfalls
      für Eingabe und Ausgabe angegeben werden.
      Dateien werden ausschließlich im Binär-Modus geöffnet.

      Dieses  dd  hat eine Fortschritt-Anzeige:  0000%%  00000 MB


      dd  berücksichtigt die folgenden Kommandozeilen-Optionen:

      if=datei            Angabe der Eingabedatei.
                          (Voreinstellung: Standard-Eingabe)
      of=datei            Angabe der Ausgabedatei.
                          (Voreinstellung: Standard-Ausgabe)

      ibs=n               Blockgröße in Bytes bei der Eingabe.
      obs=n               Blockgröße in Bytes bei der Ausgabe.
      bs=n                Blockgröße in Bytes für Eingabe und Ausgabe.
                          Vorrang vor ibs und obs.

      count=n             Anzahl der Eingabe-Blöcke,
                          die maximal gelesen werden.
                          Ohne diese Angabe wird bis Eingabeende gelesen.

      skip=n              Anzahl der Eingabe-Blöcke,
      iseek=n             die übersprungen werden, bevor gelesen wird.
                          skip erzwingt das tatsächliche Lesen von Daten
                          anstelle eines Überspringens.
                          Solchermaßen gelesene Daten werden weggeworfen.
                          Sinnvoll bei Eingabegeräten, die nicht
                          positionierbar (seekable) sind.

      seek=n              Anzahl der Ausgabe-Blöcke,
      oseek=n             die übersprungen werden, bevor geschrieben wird.

      bmode=n             Angabe derjenigen Blockgröße, mit der der
      ibmode=n            direkte Zugriff bei Ein- und Ausgabe erfolgt.
      obmode=n            (In der Regel Bytes pro Sektor bei Disks.)
                          Analog zu bs, ibs, obs;
                          bmode hat Vorrang vor ibmode und obmode.
                          Dieser Pufferungsmechanismus ist dem oben
                          beschriebenen nachgeschaltet.
                          Wenn Festplatten oder Floppies angegeben sind,
                          wird automatisch auf 512 gesetzt.
                          Explizite Angaben (2...2048) haben Vorrang.
                          Bei der UNIX-Version dieses dd-Kommandos zeigt
                          eine explizite Angabe hier an, daß der Dateiname
                          hinter if=/of= eine Disk repräsentiert.

      conv=bmode          Entspricht  bmode=512.

      conv=notrunc        Verhindert das Setzen einer vorhandenen
                          Ausgabedatei auf Dateigröße=0 vor Schreibbeginn.
                          Es kann dann mitten in eine bestehende Datei
                          hinein geschrieben werden.
                          Normalerweise werden bei seek=größer_null
                          entsprechend viele Null-Zeichen geschrieben,
                          bevor die Übertragung In->Out beginnt.
                          Disks werden selbstverständlich nicht gelöscht,
                          wenn diese Option fehlt.

      noinfo              Die Abschlußmeldung wird abgeschaltet.
                          (s.unten: DIAGNOSE) 

      calc=n              Dient zur Überprüfung der arithmetischen Ausdrücke,
                          für die ``n'' steht.
                          Beispiel:   calc=33bx4x15+1200+25-3l
                          entspricht  calc=1014973
                          x  ist ein Multiplikations-Operator.
                          b  entspricht  x512
                          k  entspricht  x1024
                          w  entspricht  x2
                          l  entspricht  x4


      Zugriff auf Festplatten und Diskettenlaufwerke:
           if= / of=hd0:c#h#s#
           if= / of=hd1:c#h#s#
           if= / of=hd2:c#h#s#
           if= / of=hd3:c#h#s#
           if= / of=fd0:c#h#s#
           if= / of=fd1:c#h#s#
           if= / of=fd2:c#h#s#
           if= / of=fd3:c#h#s#
           if= / of=hd0:       siehe nachfolgend:
      Angabe der Anzahlen für Zylinder(c)/Köpfe(h)/Sektoren(s):  c#h#s#
      Wenn die folgenden Umgebungsvariablen gesetzt sind, können diese
      Angaben in der Kommandozeile entfallen:
           DD_HD0=c#h#s#
           DD_HD1=c#h#s#
           DD_FD1=c#h#s#
           ...
      Der Doppelpunkt (:) muß dann trotzdem angegeben werden: z.B. if=hd0:
      Beispiel:
           DD_HD1=c1023h16s63     504 MB
           DD_HD2=c833h6s31        80 MB
           DD_HD0=c19650h16s63   9671 MB
           DD_HD0=c1024h255s63  <9671 MB (LBA: max.8033MB)
           DD_FD0=c80h2s18       1440 3½"
           DD_FD0=c80h2s9         720 3½"
           DD_FD1=c80h2s15       1200 5¼"
           DD_FD1=c40h2s9         360 5¼"
      Die chs-Angaben sind die Anzahlen, nicht der höchste Wert von-bis.


      Wenn von der Standard-Eingabe gelesen wird und diese mit einem
      zeichenorientierten Gerät verknüpft ist, kommt eine Spezialsyntax
      zur Eingabe von (nichtabdruckbaren) Zeichen in Funktion.
      Ein Backslash (\) gefolgt von ein bis drei Digits 0...9 wird in die
      entsprechende Zahl 0...255 umgewandelt.
      Beendet wird, sobald drei Digits gelesen wurden oder ein Nichtdigit
      erreicht ist.
      Zwei Backslash (\\) werden zu einem (\) ohne Spezialbedeutung reduziert.
      Ein \ gefolgt von einem gewöhnlichen Zeichen (alle außer [\0-9])
      ist ebenfalls gewöhnlich. Anhängende Zeilenvorschübe (NL) werden
      entfernt; man kann explizit \10 angeben.
      Mit ^D (Ctrl-D) bzw. ^Z wird eine solche Tastatur-Eingabe beendet.

      Für die Standard-Ausgabe gilt analog entsprechendes:
      Die Zeichenwerte 0-32,127,155 und 255 werden zu '\ddd' umgeformt, etc.
      Ein \ wird immer zu \\ erweitert.
      Diese Konversionen können einen Hex/Dez/Oct-Präsentator natürlich
      nicht ersetzen. Sie sind dafür, falls man einmal doch nicht mit
      Dateien arbeiten will, was für dieses Kommando untypisch ist.

      dd  versucht stets, Einheiten ausschließlich in den angegebenen
      Blockgrößen zu bilden. Dazu werden unter anderem Teilbereiche im
      Puffer verschoben. Nur ganz zum Schluß muß unter Umständen
      gestückelt werden.
      Der interne Puffer ist 63b groß. Wird eine größere Blockgröße
      angegeben, muß zwangsläufig gestückelt werden.
      Bei Disks werden unter allen Umständen nur ganze Sektoren
      gelesen oder geschrieben. Dazu wird u.a., falls erforderlich,
      ein Sektor gelesen, teilweise geändert, und anschließend als Ganzes
      zurückgeschrieben. Gleichzeitig werden stets maximal viele Sektoren
      einer Spur auf einmal gelesen oder geschrieben.


      dd  berücksichtigt auch die folgende Umgebungsvariable (Environment):
      DDAUTOR
        Um die Autorenmeldung abzuschalten:
        DDAUTOR=H.Schellong,Vlotho
      DDPROGRAM
        Um die Freeware-Meldung zu unterdrücken:
        DDPROGRAM=Freeware_nur_fuer_nichtgewerbliche_Verwendung
        DDPROGRAM=FreeLizenz_Software_von_Helmut_Schellong
        (DDAUTOR muß hierfür auch gesetzt sein.)



 WARNUNGEN
      Bei arithmetischen Ausdrücken sollte ein Minuszeichen gegebenenfalls
      nur vor der letzten Zahl stehen. Sonst gibt es unerwartete Resultate.
      Man beachte, daß bei  count,skip,seek  eine Anzahl BLÖCKE festgelegt
      wird, und nicht Bytes!

      Falls man im BIOS eine zweite Festplatte (slave) als Bootplatte
      angibt (z.B. D,A statt A,C), dann ist diese 'D' 'hd0' für 'dd'
      und die Hauptplatte 'hd1'.
      Das BIOS macht das halt so, man muß das ggf. durch Lesen
      mal probieren, ob das bei einem selbst auch so ist.

 HINWEISE
      Die Bezeichnungen  a:, b:, c:, ...  für Disks unter DOS wurden
      absichtlich nicht als Syntax gewählt, weil auf physikalische
      Laufwerke zugegriffen wird.
      Beispielsweise ist c: die DOS-Abteilung einer Festplatte und nicht
      der wirkliche Beginn, der mit Masterboot und Haupt-Partitionstabelle
      beginnt.
      Unter DOS können maximal 1023 cyl erreicht werden - über 503 MB
      kommt man also nicht hinaus!
      Mit LBA-Einstellung allerdings doch, und zwar bis 8033 MB. (s.o.)
      Per LBA können  1023*255*63+254*63+63  Sektoren erreicht werden.

      Wenn beispielsweise von einer Festplatte gelesen und in eine Datei
      geschrieben wird, wird man in der Regel eine heftige Kopfaktivität
      feststellen, weil die Datei sich meistens auf der selben Festplatte
      befindet - allerdings an anderer Position.
      Der Puffer des Kommandos ist (nur) 63*512 Bytes groß, weshalb eine
      wiederkehrende Kopfumpositionierung erfolgt.
      Anlegen der Datei in einer RAM-Disk bringt hier Abhilfe - wenn man
      sehr intensiv in dieser Weise mit dd arbeitet.
      Oder auch bs=63b als Mindestblockung angeben und mit Spur-Nummern
      anstatt mit Sektor-Nummern arbeiten;
      dennoch ist eine RAM-Disk wesentlich besser.

      Bei Floppies schlägt der erste Zugriff fast immer fehl. Zumindest
      wenn man nach Systemstart darauf zugreift, ohne irgendeinen Zugriff
      zuvor. dd versucht bis zu dreimal, erfolgreich zu sein, mit Pausen
      von einer Sekunde vor jedem Neuversuch.
      Blindlesezugriff bis dd-Exit==0 empfiehlt sich hier, falls das noch
      nicht ausreichen sollte.

      Die Optionen  bmode,ibmode,obmode,noinfo,calc  sind in den
      UNIX-Originalen dieses Kommandos nicht vorhanden.
      Das gilt auch für die speziellen Disk-Namen hd0:,..., weil unter
      UNIX Disks und alle anderen Geräte normale Dateinamen haben.
      Die Umwandlungen bei Standard-Ein- und -Ausgabe (\ddd) fehlen auch.
      Options-Arithmetik:  n:  #[{b|k|w}][x#[{b|k|w}]]...[x#[{b|k|w}]]
      Dafür fehlen diesem dd:   cbs=n und conv=conversion_option .

      Bei der Eingabe von der Tastatur ist zu beachten, daß bei einer
      angegebenen Blockgröße ibs=s / bs=s und count=n
      n Zeilen mit je s Zeichen gelesen (angefordert) werden.
      Überzählige Zeichen pro Zeile werden ignoriert.
      '\ddd' gilt selbstverständlich als ein (1) Zeichen.
      Mit ^D bzw. ^Z  kann man vorzeitig beenden. (s.o.)


 BEISPIELE
      Liest eine 1440K-Floppy und erzeugt eine Datei von 1474560 Byte Größe:
           dd  if=fd0:c80h2s18 of=datei bs=18k count=80

      Schreibt ein Byte zur Festplatte:
      Und zwar wird eine erweiterte DOS-Partition unkenntlich gemacht,
      die normalerweise \4 oder \6 dort stehen hat.
      Gelesen wird von der Standard-Eingabe.
           dd  of=hd0: bs=1 count=1 seek=828576b+450
           \000
           ^D (^Z)
      Sicherer ist der Umweg über eine Datei:
           dd  if=hd0: of=datei512 bs=1b count=1 iseek=828576   ...
           dd  if=datei512 of=hd0: bs=1b count=1 oseek=828576

      Es werden nacheinander Bootblock, Fat1, Fat2 und Root-Directory
      von einer 1440-Floppy gelesen:
           dd  if=fd0: of=boot bs=1b count=1 [iseek=0]
           dd  if=fd0: of=fat1 bs=1b count=9  iseek=1
           dd  if=fd0: of=fat2 bs=1b count=9  iseek=10
           dd  if=fd0: of=root bs=1b count=14 iseek=19

      Der Bootblock und der Anfang der ersten FAT werden gelesen:
           dd  if=hd0:c1024h255s63 of=bf bs=1b iseek=11612160 count=3
      Der Startsektor 11612160 ist beispielhaft; LBA.
           dd  if=hd0:c1024h255s63 of=bf bs=63b iseek=184320 count=1
      Dies ist die gleiche Position, nur schwächer geblockt
      und 63*512 statt 3*512 Dateigröße.
      184320 ist die Spur(track)-Nummer (11612160/63=184320).


 DIAGNOSE
      Meldung auf die Standard-Ausgabe:
           n blocks + n bytes  in
           n blocks + n bytes  out
      (Kann abgeschaltet werden.)
      Fehlermeldungen.

      Es ist eine Fortschritt-Anzeige implementiert: Promille + MByte,
      die ab 1 MB arbeitet.
      Ohne Angabe von count=x stimmt die %%-Angabe nicht.
      Auch diese Anzeige kann durch 'noinfo' abgeschaltet werden.

 EXIT-CODE
      0     Kein Fehler.
      1     Fehlerhafte Argumentliste.
      2     Benötigte Variable undefiniert.
      3     Dateiöffnen fehlgeschlagen.
      4     Fehler von Systemfunktion.
      5     Fehler beim Dateilesen.
      6     Fehler beim Dateischreiben.


 SIEHE AUCH
      bish(K), hx(K), cmp(K).


 AUTOR
      Dieses Kommando  dd  wurde entwickelt von:
      Helmut Schellong, Bad Salzuflen



^

 hx(K)                                                                    hx(K)



 NAME
      hx.exe - Wandelt Daten um in lesbare Darstellungsformen
      hx       (intern bish(K))


 SYNTAX
      hx  [-a[d][b]] [-b[d][b]] [-t[g78d]]  [-o[0]N] [-nN] [-[-]]  [datei ...]
              h  k       h  w
              H  K       H  l
                [x]N    c[g78d]

      N:  #[{b|k|w|l}][{x|+}#[{b|k|w|l}]]...[{x|+|-}#[{b|k|w|l}]]
      #:  [0]...{1-9}...[{0-9}]...



 BESCHREIBUNG
      Das Kommando  hx  liest Daten aus einer oder mehreren Eingabedateien
      und schreibt sie formatiert zur Standard-Ausgabe.
      Wenn keine Dateien angegeben sind, liest hx von der Standard-Eingabe.
      Falls diese dabei mit einem zeichenorientierten Gerät verknüpft ist,
      kann die Eingabe mittels Eingabe von ^D (Ctrl-D) bzw. ^Z beendet
      werden.
      Dateien werden ausschließlich im Binär-Modus geöffnet.
      Bei Angabe von zwei oder mehr Dateien wird der Dateiname jeweils
      zu Anfang ausgegeben.

      hx  verfügt über mehrere wählbare Darstellungsformen bei der Ausgabe.
      Für eine Zahl 'N', die an drei Stellen angegeben kann, gibt es eine
      eigene Arithmetik-Syntax (s.u.).
      hx  berücksichtigt fünf Haupt-Optionen, mit bis zu zwei Gruppen
      von dazugehörenden Unter-Optionen.


      Die Kommandozeilen-Optionen sind im einzelnen:

           -a     Darstellung der Adresse am Zeilenbeginn.
           -b     Darstellung der Bytes. (16 oder 64 pro Zeile)
           -t     Zusätzliche Textdarstellung der Bytes am Zeilenende.
           -o     Angabe, wieviel Bytes zu Beginn ignoriert werden sollen.
           -n     Angabe, wieviel Bytes (maximal) gelesen werden sollen.
           -:     Ersetzt bei einigen Formaten den ':' durch Leerzeichen.
           -      Nachfolgende Argumente werden als Dateinamen
           --     aufgefaßt, auch wenn sie mit '-' beginnen.

           -a        Darstellung der Adresse am Zeilenbeginn.
                     Ohne Unteroption wird die Adressenausgabe unterdrückt.
                 dhH
                     Darstellung dezimal, hexadezimal (abcdef)
                     oder hexadezimal (ABCDEF).
                 bkK
                     Darstellung in Anzahl Blocks plus Anzahl Bytes:  ##x+##
                     wobei x für [bkK] steht.
                     Blockgrößen:   b,k,K = 512,1000,1024
                     (Bei zu langen Zeilen wird '+' weggelassen.)
                 xN
                     Per N kann eine beliebige Blockgröße eingestellt
                     werden. x ist ein beliebiges Zeichen als Kennung.
                     (N-Syntax siehe unten.)

           -b        Darstellung der Bytes. (16 oder 64 pro Zeile)
                 dhH
                     Darstellung dezimal, hexadezimal (abcdef)
                     und(!)/oder hexadezimal (ABCDEF).
                 bwl
                     Darstellung von 16 Bytes, 8 Wörtern
                     und(!)/oder 4 Doppelworten (long).
                 c[g78d]
                     Textdarstellung, 64 Byte pro Zeile.
                     Diese Unteroption hat Vorrang vor den anderen
                     und schaltet die Hauptoption -t ab.
                     Voreingestellt ist (c)g.  ([g78d] siehe unten -t.)

           -t        Zusätzliche Textdarstellung der 16 Bytes am Zeilenende.
                     Es sind verschiedene Ersetzungen der nichtabdruckbaren
                     Zeichen und der Zeichen aus der oberen Hälfte
                     des Zeichensatzes einstellbar:
                 g   Kontrollzeichen='.';  Werte>127='·' außer äöüÄÖÜß
                 7   Werte<' ' und Werte>=127 = '.'  (ascii standard)
                 8   Kontrollzeichen='·'
                 d   Kontrollzeichen='?'; Null='_'
                     Kontrollzeichen sind:  0...31,127,155,255
                     Ohne jede Unteroption wird diese Ausgabe abgeschaltet.

           -o[0]N    Angabe, wieviel Bytes zu Beginn ignoriert werden sollen.
                     Bei Dateien (seekable) wird zur angegebenen Byte-Adresse
                     gesprungen. Beim Lesen von der Standard-Eingabe werden
                     entsprechend viele Bytes überlesen.  (Offset)
                     Eine führende Null bewirkt, daß die ausgegebenen
                     Adressen -trotz Offset- bei Null beginnen. Normalerweise
                     zeigen die Adressen die tatsächliche Byte-Adresse.

           -nN       Angabe, wieviel Bytes (maximal) gelesen werden sollen.


           Voreingestellt sind:  -adb -bhb -tg -o0 -ninf


      Syntax für N:
           N:  #[{b|k|w|l}][{x|+}#[{b|k|w|l}]]...[{x|+|-}#[{b|k|w|l}]]
           #:  [0]...{1-9}...[{0-9}]...

           x  ist ein Multiplikations-Operator.
           b  entspricht  x512
           k  entspricht  x1024
           w  entspricht  x2
           l  entspricht  x4

           Beispiel:   -n33bx4x15+1200+25-3l
           entspricht  -n1014973


      hx  berücksichtigt die folgenden Umgebungsvariablen (Environment):
      HXAUTOR
        Um die Autorenmeldung abzuschalten:
        HXAUTOR=H.Schellong,Vlotho
      HXPROGRAM
        Um die Freeware-Meldung zu unterdrücken:
        HXPROGRAM=Freeware_nur_fuer_nichtgewerbliche_Verwendung
        (HXAUTOR muß hierfür auch gesetzt sein.)
      Dies gilt nicht für das bish-interne hx.



 WARNUNG
      Bei arithmetischen Ausdrücken sollte ein Minuszeichen gegebenenfalls
      nur vor der letzten Zahl stehen. Sonst gibt es unerwartete Resultate.

 HINWEISE
      Die Unteroptionen werden nicht auf Fehlerhaltigkeit geprüft.
      Es werden von links nach rechts alle bekannten Optionen berücksichtigt,
      die -gegebenenfalls- vorher angegebene überschreiben oder rücksetzen.
        Man beachte, daß per Option -b ein und dieselbe Zeile bis zu
      neunmal in jeweils unterschiedlichem Format ausgegeben werden kann.
      Die Reihenfolge in den Unteroptionsgruppen wird berücksichtigt.
        Die zusätzliche Textausgabe per Option -t wird automatisch abgestellt,
      falls dadurch eine Zeile zu lang würde.
        Bei Darstellung von Wörtern oder Doppelwörtern kommt es vor, daß
      zum Schluß in der letzten Zeile weniger als 2 bzw. 4 Bytes pro Einheit
      vorhanden sind. In diesen Fällen werden auch die unvollständigen
      Einheiten dargestellt, entsprechend viele Null-Bytes enthaltend.


 BEISPIELE
      dd if=fd0: ...  |  hx -n16x23
      Bringt die Daten, die das dd-Kommando ausgibt, in einer lesbaren
      Form auf den Bildschirm.

      dd if=fd0: ...  |  hx  |  pg
      Erweitert die Pipeline um das Kommando pg, ein Pager-Programm,
      das seitenweises Betrachten ermöglicht, ähnlich wie more.

      hx -n50 datei
      0b+000  4c 01 04 00 db 91 e4 30  00 00 00 00 00 00 00 00  L...···0.......
      0b+016  1c 00 0f 01 0b 01 00 00  40 11 00 00 6c 02 00 00  ........@...l..
      0b+032  c4 02 00 00 d4 00 00 00  d0 00 00 00 10 02 40 00  ·...·...·.....@
      0b+048  2e 74                                             .t

      hx -blh -n50 datei
      0b+000    0004014c    30e491db    00000000    00000000  L...···0........
      0b+016    010f001c    0000010b    00001140    0000026c  ........@...l...
      0b+032    000002c4    000000d4    000000d0    00400210  ·...·...·.....@.
      0b+048    0000742e                                      .t


 DIAGNOSE
      Fehlermeldungen.

 EXIT-CODE
      0     Kein Fehler.
      1     Fehlerhafte Argumentliste.
      2     Dateiöffnen fehlgeschlagen.
      3     Fehler von Systemfunktion.
      4     Fehler beim Dateilesen.


 SIEHE AUCH
      bish(K), pg(K), more(DOS), dd(K).


 AUTOR
      Dieses Kommando  hx  wurde entwickelt von:
      Helmut Schellong, Vlotho
      Copyright © 1995-2016





^

 ov(K)                                                                    ov(K)



 NAME
      ov.com - Setzt die Farbe der Overscan-Region des Bildschirms


 SYNTAX
      ov  [-q] [0...63]
      prev=`ov #`
      curr=`ov`



 BESCHREIBUNG
      Das Kommando  ov  setzt die Farbe des äußersten Bildschirmrandes
      auf den angegebenen Wert.

      Der vorher eingestellte Wert wird zur Standard-Ausgabe geschrieben,
      sofern nicht Option -q gegeben ist, bei der der Exit-Wert des
      Kommandos auf den vorher gültigen Farbwert gesetzt wird.
      Bei fehlendem Zahlenwert wird lediglich das Setzen auf eine neue
      Farbe unterlassen.

      Es werden Werte von 0 bis 255 an die Hardware übermittelt
      als auch von der Hardware gelesen.
      Der Wert 63 ist jedenfalls für Standard-VGA der höchste,
      höherwertige Bits werden hier von der Hardware ignoriert.

      Das Kommando ist wegen der dort vorhandenen Kommando-Substitution
      im Zusammenhang mit einem Shell-Programm wie 'bish' nützlich.



 BEISPIELE
      ov  22
      ov -q 22               Ausgabe des vorherigen Wertes unterdrückt.
      prev=`ov 9`            Vorheriger Wert in Variable prev.
      curr=`ov`              Aktueller Wert in Variable curr.
      ov -q ; curr=$?        dito


 SIEHE AUCH
      bish(K)

 EXIT-CODE
      0...  Farbwerte bei Option -q


 AUTOR
      Das Programm  ov  wurde entwickelt von:
      Helmut Schellong, Bad Salzuflen
      Copyright © 1997



^

 pg(K)                                                                    pg(K)



 NAME
      pg.exe - Kommando zum komfortablen Lesen von Textdateien (pager)
      pgr      (intern bish(K))

 SYNTAX
      pgr  [-] [-zahl] [-cefns] [ datei(en) ...]



 BESCHREIBUNG
      Das Kommando  pgr  erlaubt die seitenweise Betrachtung der Inhalte
      vorzugsweise von Textdateien.
      Wenn die Kommandozeilen-Option '-' und/oder wenn keine Datei
      angegeben ist, liest pgr von der Standard-Eingabe.
      Die Ausgabe erfolgt auf die Standard-Ausgabe.
      Durch Betätigung der <Enter>-Taste wird jeweils die nächste Seite
      ausgegeben.
      Mit pgr kann innerhalb eines Dateiinhaltes beliebig vor und zurück
      gesprungen werden, was ebenfalls für die Suchmuster-Funktion gilt.
      Aus diesem Grund erzeugt pgr eine temporäre Datei, wenn ein
      Datenstrom von der Standard-Eingabe gelesen wird.

      pgr berücksichtigt folgende Shell-Variablen:
      PGTEMP
        zur Angabe eines Verzeichnisses für die temporäre Datei.
        Standard-Verzeichnis ist das bish-Temp-Verzeichnis.
      PGCOLUMNS
        Standardwert ist 130.
      PGLINES
        Standardwert ist 30.

      Die Kommandozeilen-Optionen sind:

      -zahl    Anzahl Zeilen, die pro Seite ausgegeben werden.
               Wegen der Seiten-Eingabeaufforderung (s: ) wird
               standardmäßig LINES-1 (29) eingestellt.
               Wenn dieser Wert LINES-1 ist, wird zwar die
               gewählte Anzahl von Zeilen jedesmal ausgegeben,
               jedoch wird zuvor um eine Zeile zurückpositioniert,
               damit die zuvor letzte sichtbare Zeile auf der
               jetzt aktuellen Seite zuoberst noch einmal
               sichtbar wird. (siehe Bedienungs-Kommando w)

      -c       Stellt den Cursor nach links oben und löscht den
               Bildschirm, bevor jeweils eine Seite geschrieben
               wird.
               Wird automatisch unterdrückt bei dem
               Bedienungskommando <l> bzw. <Down>.

      -e       Bei Dateiende entfällt das Prompt (EOF)s: ,
               und wenn die letzte Dateizeile bzw. die letzte
               Zeile der letzten Datei ausgegeben wurde, beendet
               pgr automatisch.

      -f       Unterdrückt das Einfügen der Zeichen CR-NL.
               Ohne diese Option zerschneidet pgr Zeilen,
               sobald COLUMNS-1 Zeichen gezählt wurden.

      -n       Durch Angabe dieser Option muß die Mehrzahl der
               Bedienungskommandos nicht mehr durch <Enter>
               abgeschlossen werden - ein einfacher Tastendruck
               genügt.
               Desweiteren werden einige zusätzliche
               Funktionstasten aktiviert.

      -s       Das Seiten-Prompt erscheint schwarz auf weiß (invers).



      Zur Bedienung stehen die folgenden Kommandos zur Verfügung:

      <h>  <F1>                  Zeigen einen Hilfetext.
      <q>  <Q>                   Beenden pgr.

      <Enter>  < >  <PgDown>     Eine Seite vor.
       +  +n                     Eine bzw. n Seiten vor.
      <PgUp>                     Eine Seite zurück.
       -  -n                     Eine bzw. n Seiten zurück.
       n                         Zur n-ten Seite.
      <l>  <Down>                Eine Zeile vor.
      <$>  <End>                 Zur letzten Seite.
           <Home>                Zur ersten Seite.

       /suchmuster               Sucht vorwärts nach suchmuster.
       ?suchmuster               Sucht rückwärts nach suchmuster.
      <N>                        Sucht nächstes Vorkommen.

      <n>                        Zur nächsten Datei.
      <p>                        Zur vorherigen Datei.

       !kommando [arg ...]       Führt 'kommando' aus.

       s datei                   Aktuelle Datei wird in datei gesichert.
                                 Das funktioniert auch mit der temporären
                                 Datei, beim Lesen von der Standardeingabe.

       w[n]                      Anzahl (n) Zeilen pro Seite.
                                 w stellt ein auf LINES-1.
                                 (s. Kommandozeilen-Option -zahl)

      <.>                        Schreibt aktuelle Seite erneut.

      Bei Aufruf mit Option -n funktionieren die <Tasten>,
      ohne daß mit <Enter> abgeschlossen werden muß.

      Bei Endposition (EOF) sind die Zeichen oder <Tasten> zum Beenden oder
      Dateiwechsel gesperrt. Es können dann '$' <$> <End> benutzt werden.
      Dies, damit nicht unabsichtlich aus der Datei 'herausgerutscht' wird.


      Die Suchmuster-Funktion sucht ab der obersten sichtbaren
      Zeile vorwärts bzw. rückwärts.
      Wenn ein Muster gefunden wurde, wird die entsprechende
      Zeile als oberste Bildschirmzeile geschrieben.
      Wenn mittels des Kommandos <N> nach weiteren Vorkommen
      gesucht wird, wird zuvor eine Zeile weiter- bzw.
      zurückpositioniert.
      In einem Suchmuster werden diejenigen Zeichen, die unter
      UNIX zur Dateinamen-Expansion dienen, als Spezialzeichen
      mit ebensolcher Funktion interpretiert.
      Zusätzlich haben die Zeichen ^ und $ Sonderbedeutung.
      Um diese Spezialbedeutung aufzuheben, muß das Zeichen %
      vorangestellt werden, was auch für % selbst gilt.
      Das Zeichen % wird als normales Zeichen aufgefaßt, wenn es
      nicht vor einem Zeichen mit (aktiver) Spezialbedeutung steht.
      Dabei ist zu beachten, daß ^ und $ nur an bestimmten
      Positionen Sonderbedeutung haben!
      Die Begrenzungszeichen / und ? haben nur als erstes
      Zeichen diese Spezialbedeutung. Sie dienen nur zur
      Suchrichtungsauswahl und werden nach Erfüllung dieser
      Aufgabe einfach entfernt.

      ?       Steht für ein beliebiges Zeichen.
      *       Ersetzt beliebig viele beliebige Zeichen,
              also auch null Zeichen.
      [...]   Zeichenklasse:
              Ersetzt ein (1) Zeichen, das in der Zeichenklasse
              vorkommt bzw. nicht vorkommt.
              Innerhalb einer Zeichenklasse haben nur die
              Zeichen !, - und ] eine Spezialbedeutung.
           !  Wenn ! [ direkt folgt ([!...]), werden Zeichen
              ersetzt, die nicht unter denen in der Klasse
              angegebenen sind.
           -  Mit - können Zeichenbereiche in Kurzschreibweise
              definiert werden:
              [a-fu-zA-C]  entspricht  [abcdefuvwxyzABC]
              Das jeweils rechte Zeichen muß bezüglich seiner
              Position im Zeichensatz gleich oder größer als
              das linke Zeichen sein.
              Das Minuszeichen hat nur diese Bedeutung, wenn es
              nicht am Rand steht, sondern zwischen Zeichen, die
              als Klassenzeichen interpretiert werden.
              [--d]  ersetzt alle Zeichen von - bis d.
              [a-d-z]  wird als  [a-dd-z]  interpretiert.
              [a#--bc]  entspricht  a oder # bis - oder b oder c.
           ]  Das Zeichen ] ist das Abschlußzeichen einer
              Zeichenklasse.  Wenn es [ oder [! direkt folgt,
              wird es als Zeichen ohne diese Abschlußwirkung
              interpretiert.
      ^       Erzwingt, daß das Suchmuster am Anfang einer Zeile
              passen muß:  /^suchmuster
      $       Erzwingt, daß das Suchmuster am Ende einer Zeile
              passen muß:  /suchmuster$
              /^$  sucht beispielsweise nach Leerzeilen.
              Diese beiden Zeichen ^ und $ haben nur Spezialbedeutung
              am Anfang bzw. am Ende eines Suchmusters.


      pgr ist nicht interaktiv, wenn die Standardausgabe nicht
      mit einem Terminal/Console/Gerät verbunden ist.

      Die Zeichen mit den folgenden Dezimalwerten werden von pgr
      in das Zeichen ~ umgewandelt:
      0-31 (außer TAB, CR, NL und ESC), 255

      pgr berücksichtigt folgende Umgebungsvariablen (Environment):
      (nicht bish-intern)
      PGAUTOR
        Um die Autoren-Meldung zu unterdrücken:
        PGAUTOR=H.Schellong,Vlotho
      PGPROGRAM
        Um die Freeware-Meldung zu unterdrücken:
        PGPROGRAM=Freeware_nur_fuer_nichtgewerbliche_Verwendung
        (PGAUTOR muß hierfür auch gesetzt sein.)


 BEISPIELE
      pgr -nc datei1 datei2 ...
      pgr < datei
      dir | pgr -nce
      type datei1 | pgr -f > datei2

 NOTA
      pgr expandiert grundsätzlich keine Argumente (mit * oder ?),
      sondern erwartet diesen Service von einem Shell-Programm,
      wie beispielsweise bish(K).

      Die erhöhte Funktionalität der unix-typischen
      "Regulären Ausdrücke" wurde absichtlich nicht implementiert,
      weil diese im Zusammenhang mit dem Zweck dieses Programms
      erstens nicht nötig und zweitens, unpraktischer ist,
      weil komplizierter und langwieriger formuliert werden muß.

      pgr geht davon aus, daß TABs 8er-Schritte produzieren.

      Zahlenbereich für LINES  :  3...63
      Zahlenbereich für COLUMNS:  9...512

      pgr kann maximal 33.554.432 Dateizeilen verarbeiten.
      Unter Windows die Hälfte davon.
      Das entspricht normalerweise mehr als einem GigaByte Dateigröße.
      Eine Zeile wird abgeschlossen durch das Zeichen NL
      oder sobald COLUMNS-1 Zeichen gezählt wurden.
      (Option -f ist bei dieser Betrachtung bedeutungslos.)

      pgr fügt ein Zeichen CR am Zeilenende ein, wenn dort nur
      das Zeichen NL vorgefunden wird und wenn die Standard=
      ausgabe mit einem Gerät verbunden ist.

      pgr berücksichtigt Tastenprogrammierungen, die auf Betriebssystemebene
      mittels Escape-Sequenzen vorgenommen wurden.
      Wer also beispielsweise eine US-Tastatur hat und <Alt>a = ä
      programmiert hat, kann dies auch so innerhalb von pgr benutzen.

      Man beachte bei Verwendung des Kommandos $ oder <End>
      und gleichzeitigem Lesen von der Standardeingabe, daß der
      gelesene Datenstrom beliebig groß werden kann!

      Dieses Programm pgr verarbeitet die Daten mit mehrfach
      verschachtelter Pufferung und arbeitet u.a. deshalb
      um ein Vielfaches schneller als die Originale
      auf verschiedenen UNIX-Systemen.


 SIEHE AUCH
      regexp®

 EXIT-CODE
      0     Kein Fehler aufgetreten.
      1     Allgemeiner Fehler (Argumente, falsche Datei, etc.)
      2     Wenn eine Systemfunktion einen Fehler meldete.

 AUTOR
      Dieses Programm  pgr  wurde entwickelt von:
      Helmut Schellong, Vlotho
      Copyright © 1995-2016



^

 timex(K)                                                              timex(K)



 NAME
      timex.exe - Mißt den Zeitbedarf einer Kommandoausführung

 SYNTAX
      timex  kdo.exe [kdo_args]



 BESCHREIBUNG
      Das Kommando  timex  interpretiert seine Argumente
      als Name einer ausführbaren Datei, gefolgt von optionalen
      Argumenten dazu, und bringt das angegebene Kommando zur Ausführung.
      Die Zeit, die das Kommando benötigte, wird in Sekunden
      mit zwei Nachkommastellen zur Standard-Ausgabe geschrieben: 'SS.ss'

      Die Auflösung beträgt 1/100 Sekunde.
      Wegen der höheren Auflösung wird anstelle eines 'Clock-Ticks'
      die Systemzeit zur Messung verwendet.
      Das Zeitnahme-Kommando darf daher nicht die Systemzeit ändern.
      Die Systemzeit darf während der Messung über 00:00:00 Uhr gehen,
      da diese Möglichkeit berücksichtigt wurde.

      timex  berücksichtigt die folgenden Umgebungsvariablen (Environment):
      BSHAUTOR
        Um die Autoren-Meldung zu unterdrücken:
        BSHAUTOR=H.Schellong,Vlotho
      TIMEXPROGRAM
        Um die Freeware-Meldung zu unterdrücken:
        TIMEXPROGRAM=Freeware_nur_fuer_nichtgewerbliche_Verwendung
        (BSHAUTOR muß hierfür auch gesetzt sein.)


 BEISPIEL
      timex  hx datei  >> sec.tim
      Die gemessene Zeit wird dem Inhalt von sec.tim hinzugefügt.
      (timex erhält die Argumente 'hx' und 'datei'.)

      timex  hx datei  ">>" sec.tim
      hx versucht, die Dateien datei, >> und sec.tim zu lesen,
      was sicher nicht beabsichtigt war.

      timex  command.com /c copy datei \verz


 DIAGNOSE
      Bei Fehlern wird keine Zeit ausgegeben.

 EXIT-CODE
      0     Kein Fehler.
      1     Fehler bei Zeitnahme oder Kommandoausführung.


 SIEHE AUCH
      bish(K).


 AUTOR
      Dieses Kommando  timex  wurde entwickelt von:
      Helmut Schellong, Bad Salzuflen



^

 touch(K)                                                              touch(K)



 NAME
      touch.exe - Setzt Datum und Zeit von Dateien

 SYNTAX
      touch  [ -amc ]  [ /TT[MM[JJ[hh[mm[ss]]]]] ]  datei ...
      touch  [ -amc ]  [ -MMTThhmm[JJ] ]            datei ...



 BESCHREIBUNG
      Das Kommando  touch  setzt die Modifikationszeit von einer oder
      mehreren Dateien.
      Angegebene Dateien, die zuvor nicht existieren, werden erzeugt
      und haben dann eine Größe von 0 Byte.
      Option  -c  unterbindet diese Erzeugung von nichtexistenten Dateien.
      Die Optionen  -a -m  haben unter DOS keine Wirkung.

      Für eine fehlende Zeitangabe wird die aktuelle Zeit eingesetzt.
      Zur Zeitangabe stehen zwei Varianten zur Verfügung:
           -MM...     Kompatibel mit dem UNIX-Original-Kommando.
           /TT...     Datum und Uhrzeit in deutscher Reihenfolge.
      Bedeutung der Buchstaben in der Zeitangabe:
           Tag, Monat, Jahr, hour(Stunde), minute, sekunde.
      Es müssen gegebenenfalls führende Nullen (0) angegeben werden.

      Bei der Zeitangabe können -von hinten begonnen- bis zu fünf
      Teilangaben weggelassen werden, wie es durch die eckigen Klammern
      angedeutet ist.
      Für fehlende Teilangaben werden dann die entsprechenden Teile der
      vorhandenen Dateizeit eingesetzt, oder -bei zuvor nichtexistenten
      Dateien- die entsprechenden Teile der aktuellen Zeit.

      Als Jahreszahl können Werte von  00 bis 99  angegeben werden.
      Daraus resultieren die Jahre 1980 bis 2079.
      (80...99 --> 1980...1999  und  00...79 --> 2000...2079)

      touch  berücksichtigt die folgenden Umgebungsvariablen (Environment):
      BSHAUTOR
        Um die Autoren-Meldung zu unterdrücken:
        BSHAUTOR=H.Schellong,Vlotho
      TOUCHPROGRAM
        Um die Freeware-Meldung zu unterdrücken:
        TOUCHPROGRAM=Freeware_nur_fuer_nichtgewerbliche_Verwendung
        (BSHAUTOR muß hierfür auch gesetzt sein.)



 BEISPIELE
      touch /011194223344 datei1 datei2 datei3 datei4 datei5
      Setzt die Dateizeiten auf 1.11.1994, 22:33:44 Uhr.

      touch /010395141000  .\wk??*\??*.exe
           oder
      touch -0301141095  .\wk??*\??*.exe
      Setzt die Zeiten auf 1.3.1995, 14:10 Uhr.
      Das DIR-Kommando zeigt dann als Uhrzeit  2:10p.
      Software-Firmen verwenden dies stets als Versionskennzeichnung.
      Die Argumentbildung kann hier nur mittels bish.exe erfolgen!


 EXIT-CODE
      0     Kein Fehler.
      1     Fehler bei den Optionen.
      2     Fehler von System-Funktionen.


 SIEHE AUCH
      bish(K), mtime(bish(K)), dat(K).


 AUTOR
      Dieses Kommando  touch  wurde entwickelt von:
      Helmut Schellong, Bad Salzuflen



^


========================================================================
                           -- Editor  vi --
DIESE DATEI GEHÖRT NICHT ZUR bish-DOKUMENTATION, SONDERN IST EINE ZUGABE!
========================================================================
<Esc>  -->  Kommando-Modus
········································································
i      -->  Schreib-Modus: links einfügen  (#i)
I      -->  Schreib-Modus: springt zum sichtb. Zeilenanfang, dann wie i
a      -->  Schreib-Modus: rechts anhängen  (#a)
A      -->  Schreib-Modus: springt zum Zeilenende, dann wie a  (#A)
r      -->  Schreib-Modus: ein Zeichen überschreiben
3r     -->  Schreib-Modus: eingegebenes Zeichen 3-mal
R      -->  Schreib-Modus: beliebig viele Zeichen überschreiben
4R     -->  Schreib-Modus: eingegebene Zeichenfolge 4-mal
o      -->  Schreib-Modus: Anfang nächste Zeile
O      -->  Schreib-Modus: Anfang Zeile darüber
cc     -->  Schreib-Modus: löscht Zeile und geht zum Anfang  (#cc)
cw     -->  Schreib-Modus: ändert Wort          (3cw = 3 Worte)
cW     -->  Schreib-Modus: dito - Trennzeichen nur noch ' '
C      -->  Schreib-Modus: ändert bis Zeilenende  (#C)
c$     -->  Schreib-Modus: ändert bis Zeilenende  (#c$)
c0     -->  Schreib-Modus: ändert bis Zeilenanfang
c^     -->  Schreib-Modus: ändert bis sichtbaren Zeilenanfang
c4_    -->  Schreib-Modus: ändert die nächsten 4 Zeichen    (_ = space)
4c_    -->  Schreib-Modus: ändert die nächsten 4 Zeichen    (_ = space)
cfz    -->  Schreib-Modus: ändert bis EINschließlich nächstes z
2cfz   -->  Schreib-Modus: ändert bis EINschließlich übernächstes z
c2fz   -->  Schreib-Modus: dito
ctz    -->  Schreib-Modus: ändert bis AUSschließlich nächstes z
s      -->  Schreib-Modus: ersetzt 1 Zeichen    (5s = 5 Zeichen)
S      -->  Schreib-Modus: ändert  1 Zeile      (5S = 5 Zeilen)
········································································
<Ctrl><u>   Beginnt Schreibvorgang neu  (im Schreib-Modus!)
<Ctrl><w>   Beginnt Schreibvorgang neu  (im Schreib-Modus!)
<Ctrl><d>   Cursor links bei autom. Zeicheneinfügung (set autoindent)
········································································
<Ctrl><v> , <Enter>  schreibt z.B. ^M
So werden Steuer-Zeichen geschrieben, die sonst aktiv würden.
------------------------------------------------------------------------
<Ctrl><g>   Gibt Information über aktuelle Datei  (:f = dito)
------------------------------------------------------------------------
AUF VIELFÄLTIGE MÖGLICHKEITEN, KOMMANDOS ZU KOMBINIEREN, ACHTEN.
Zahlen lassen sich vor nahezu alle Kommandos setzen, auch wenn hier
nicht unbedingt überall angegeben (# ) !
Es handelt sich um Wiederholungsanzahlen oder (Zeilen-)Adressierungen.
Viele Kommandos wirken nur in der aktuellen Zeile (z.B. #ctz) !
------------------------------------------------------------------------
x      löscht Zeichen    (5x   =Fünf Zeichen)
X      löscht Zeichen, jedoch links vom Cursor   (5X)
dw     löscht Wort       (4dw)
dW     dito - Trennzeichen nur noch ' '
dd     löscht Zeile(n)   (3dd  =Drei Zeilen)
D      löscht Zeile bis Zeilenende, ab Cursor
d$     löscht Zeile bis Zeilenende, ab Cursor    (#d$)
d0     löscht Zeile bis Zeilenanfang, ab Cursor
d^     löscht Zeile bis sichtbaren Zeilenanfang, ab Cursor
d5_    löscht 5 Zeichen/Zeilen durch <Space>-drücken, <BackSp>, j oder k
5d_    löscht 5 Zeichen durch <Space>-drücken
dtS    löscht analog zu ctz, yfs, etc. - also bis ausschl. nächstes S
d/wu   löscht bis ausschließlich 1. Vorkommen von 'wu'.
········································································
:34d             Löscht Zeile 34
:12,14d          Löscht Zeilen 12 bis 14
:'a,'bd          Löscht Zeilen zwischen den Marken (s.u.) a und b.
:12,$d           Löscht ab Zeile 12 bis Datei-Ende
:.,$d            Löscht ab aktueller Zeile bis Datei-Ende
:1,$d            Löscht gesamte Datei
:%d              Löscht gesamte Datei  (% = 1,$)
:g/ABC/d         Löscht alle Zeilen, die ABC enthalten
:g/^$/d          Löscht alle Leerzeilen
:12,76s/ABC//g   Löscht sämtliche ABC in den Zeilen 12 bis 76
:g/ABC/s///      Löscht jeweils das erste ABC in allen Zeilen
:g/ABC/s///g     Löscht sämtliche ABC
------------------------------------------------------------------------
J      Zeile unter der aktuellen wird an aktuelle angehängt
1J,2J  dito, verketten 2 Zeilen
4J     Jetzt werden 4 verkettet, also 3 an die aktuelle gehängt.
       <Enter> beim Schreiben ist Zeilenbrechen
               und damit Rückgängigmachung (siehe auch <r><Enter>) !
~      Ändert von Kleinschreibung zu Großschreibung und umgekehrt
8~     dito - jetzt aber 8 Zeichen
.      Wiederholt letzten Schreib- oder Löschvorgang inklusive <Esc>
       (auch z.B.  "aP  ;  Wirkung nach  u  beachten)     (#.)
3.     Wiederholt 3-mal
u      Macht letztes Kommando rückgängig   (Text löschen oder erzeugen)
U      Restauriert die aktuelle beliebig (oft) bearbeitete Zeile
------------------------------------------------------------------------

------------------------------------------------------------------------
$      Geht zum Zeilenende
0      Geht zum Zeilenanfang
^      Geht zum ersten sichtbaren Zeichen der Zeile
12|    Geht zum 12. Zeichen in aktueller Zeile
w      Geht zu Wortanfängen                (#w)
W      Geht zu Wortanfängen                (#W) (andere Stop-Bewertung)
b      Geht zu Wortanfängen, rückwärts     (#b)
B      Geht zu Wortanfängen, rückwärts     (#B) (andere Stop-Bewertung)
e      Geht zu Wortenden                   (#e)
E      Geht zu Wortenden                   (#E) (andere Stop-Bewertung)
fx     Geht zum nächsten x                 (#fx)
Fx     Geht zum nächsten x, rückwärts      (#Fx)
tz     Geht bis vor nächstes z             (#tz)
Tz     Geht bis vor nächstes z, rückwärts  (#Tz)
;  ,   betreffen  f, F, t, T :  springen zu weiteren Antreffen  (#;,)
········································································
%      Geht zu Klammern, wenn man dazwischen oder drauf ist. () [] {}
(  )   Geht zum Anfang/Ende von Sätzen, die mit . ? ! und '  ' enden.
{  }   Geht zum Anfang/Ende von Paragraphen  (leere Zeilen, u.a.)
[[ ]]  Geht zum Anfang/Ende von Sektionen  (^L oder { am ZA, u.a.)
········································································
123G   Geht zur Zeile 123
G      Geht zum Datei-Ende
100+   Geht 100 Zeilen vor
100-   Geht 100 Zeilen zurück
:1     Geht zur ersten Zeile = Datei-Anfang   (:0 = dito)
:123   Geht zur Zeile 123
:$     Geht zum Datei-Ende
········································································
ma     markiert aktuelle Stelle und benamt sie mit a  (a-z)
`a     springt zur markierten Stelle a
'a     springt zur markierten Stelle a, jedoch an den Zeilen-Anfang
``     springt stets zum letzten Aufenthaltsort
''     springt stets zum letzten Aufenthaltsort, jedoch an den ZA
········································································
z.     Stellt Cursor-Position auf Bildschirm-Mitte und zieht Text mit.
z8.    Reduziert Fenster auf 8 Zeilen und stellt Cursor auf Bildmitte.
········································································
<Pfeil>       Vier Pfeiltasten zur Bewegung, AUCH im Schreib-Modus.
4<Pfeil>      Bewegung um 4 Zeichen/Zeilen.
<BackSp> o. h Bewegt nach links
<Space>  o. l Bewegt nach rechts
<Enter>  o. + Bewegt nach unten, aber Cursor immer am ersten Zeichen
j             Bewegt nach unten
k             Bewegt nach oben
-             Bewegt nach oben, aber Cursor immer am ersten Zeichen
6-            Bewegt 6 Zeilen aufwärts
<Page Up>     Eine  Seite hoch
<Page Down>   Eine  Seite runter
<Ctrl><b>     Eine  Seite hoch
3<Ctrl><f>    Drei  Seiten runter
4<Ctrl><u>    (Halbe) Seite hoch     (Zahl davor bleibt in Erinnerung!)
8<Ctrl><d>    (Halbe) Seite runter   (                "               )
<Home>        Cursor nach links oben in die Ecke  (<H> = dito)
4H            Wie Home, jedoch in die vierte Bildzeile von oben
7L            Wie H, jedoch in die siebte Bildzeile von unten
M             Cursor auf mittlere Bildzeile
········································································
n                    Geht zum nächsten Suchmuster
N                    Geht zum nächsten Suchmuster, rückwärts
/suchmuster          Geht zum 'suchmuster'
:/suchmuster         Geht zum 'suchmuster'
:/such muster        Geht zum 'such muster'
:/such muster/       Geht zum 'such muster'
/such muster/2+3     Geht zum 2. Vorkommen und dann 3 Zeilen tiefer
?such muster?        Geht zum 'such muster', aber sucht rückwärts
:?such muster?       Geht zum 'such muster', aber sucht rückwärts
:g/suchmuster/p      Druckt alle Zeilen mit 'suchmuster'
:23,44g/suchmuster/p dito, aus Zeilen 23-44
:g!/suchmuster/p     Druckt alle Zeilen, mit NICHT 'suchmuster'
:v/suchmuster/p      dito
Bei /... und ?... ist ':'(ex-Editor) nicht nötig!
········································································
Suchmuster bleibt während vi-Sitzung erhalten. (n N :n)
------------------------------------------------------------------------

------------------------------------------------------------------------
yy     Kopiert aktuelle Zeile in unbenamten Speicher 0  (yy == 1yy)
12yy   Kopiert 12 Zeilen ab und einschl. akt. in unbenamten Speicher 0
y3j    Kopiert akt. Zeile und 3 darunter in unbenamten Speicher 0
y3+    dito
y4k    Kopiert akt. Zeile und 4 darüber  in unbenamten Speicher 0
y4-    dito
3yw    Kopiert 3 Worte in Speicher 0
y3w    Kopiert 3 Worte in Speicher 0
yL     Kopiert akt. Zeile und alle bis Bildende in unbenamten Speicher 0
y'o    Kopiert Zeile mit Marke  o  bis akt. Zeile  bzw.  umgekehrt
y`o    Kopiert Zeichen von Marke  o  bis akt. Zeichen  bzw.  umgekehrt
"byH   Kopiert akt. Zeile und alle bis Bildanfang in den Speicher b
"by'o  Kopiert in den Speicher b   (siehe y`o und ma)
"ay3+  Kopiert 4 Zeilen in mit a benamten Speicher
"a4yy  Kopiert 4 Zeilen in mit a benamten Speicher
"A2yy  Kopiert 2 Zeilen in a.  Hängt hinten an !!    (a-z)  >>(A-Z)
········································································
p      Kopiert yy-Zeile(n) hinter aktuelle Zeile, aus dem Speicher 0
P      Kopiert yy-Zeile(n) vor    aktuelle Zeile, aus dem Speicher 0
"ap    Kopiert yy-Zeile(n) hinter aktuelle Zeile, aus dem Speicher a
"aP    Kopiert yy-Zeile(n) vor    aktuelle Zeile, aus dem Speicher a
"4p    Kopiert yy-Zeile(n) hin. aktuelle Zeile, aus dem Speicher 4 (1-9)
"6P    Kopiert yy-Zeile(n) vor  aktuelle Zeile, aus dem Speicher 6 (1-9)
········································································
Nur die Inhalte von a-z bleiben erhalten, solange man im vi ist!
Löschspeicher 0 und 1-9 sind permanent vorhanden, aber man sollte
nicht in sie schreiben, weil es ein Stack ist, der sich laufend
verändert.
Aber man kann vor einigen Aktionen Gelöschtes wieder auffinden.
········································································
@a     Meldet, falls Speicher a leer ist, sonst undefiniertes Verhalten.
       (a-zA-Z). Undokumentiert! Sollte nicht benutzt werden!
------------------------------------------------------------------------
:m16             Bewegt aktuelle Zeile hinter Zeile 16.
:19m16           Bewegt Zeile 19 hinter Zeile 16.
:12,14m17        Bewegt  Zeilen 12 bis 14 hinter Zeile 17
:m+              Vertauscht aktuelle Zeile mit der darunter.
:m-2             Vertauscht aktuelle Zeile mit der darüber.
:m3+2            Bewegt aktuelle Zeile hinter Zeile 5.
:g/^X.*D.*[0-9]/m0
                 Die Zeilen, die mit X beginnen, dann nach beliebigen
                 Zeichen D und dann nach beliebigen Zeichen eine Zahl
                 0 bis 9 enthalten, werden nach Zeile 0 bewegt.
:'a,'bm.         Zeilen von a- bis b-Marke (<m><a> <m><b>) werden
                 hinter die aktuelle Zeile bewegt.
:12,14co0        Kopiert Zeilen 12 bis 14 hinter Zeile 0, also vor 1.
:g/xABCy/co28    Alle Zeilen, die xABCy enthalten, werden hinter 
                 Zeile 28 kopiert.
:3,72g/xABCy/co$ dito, beschränkt auf Zeilen 3-72, co>>Dateiende
:12p             Zeigt Zeile 12
:12,23p          Zeigt Zeilen 12 bis 23
········································································
Unterschied zwischen Vorwärts- und Rückwärts-Kopieren (co0, co$):
nämlich die dann vorliegende Reihenfolge der Zeilen!  (co$ behält bei)
ES GIBT DIE ZEILE  0  = Puffer-Anfang!
EIN PUNKT '.' (:.) adressiert stets die aktuelle Zeile!
········································································
:>               Schiebt aktuelle Zeile um 'shiftwidth' nach rechts
:>>>>            Um 4mal 'shiftwidth'  (i.d.R. = 8; siehe ':set all')
:<<<<            dito, nach links
:108>            Zeile 108 nach rechts
:44,69>          Zeilen 44 bis 69 nach rechts
>4j              Aktuelle und 4 weitere Zeilen darunter nach rechts
4>j              dito              (siehe Kommandos:  c, y, j, k, etc.)
4>+              dito              (siehe Kommandos:  c, y, j, k, etc.)
4>>              Vier Zeilen nach rechts, ab aktueller
4<<              dito, nach links
------------------------------------------------------------------------

------------------------------------------------------------------------
:12,17s/ABC/CBA/     Ersetzt in Zeilen 12 bis 17 'ABC' durch 'CBA'
                     (nur jeweils erstes Vorkommen in den Zeilen)
:12,17s/ABC/CBA/g    Ersetzt in Zeilen 12 bis 17 'ABC' durch 'CBA'
                     (g = jeweils jedes Vorkommen in den Zeilen)
:2,333s/^/** /       Fügt an den Zeilenanfängen 2 bis 333 '** ' ein.
:g/^/s// w /         Fügt an allen Zeilenanfängen ' w ' ein.
:g/$/s// w /         Hängt an alle Zeilenenden ' w ' an.
:g/xyz$/s//XYZ/      Ersetzt alle 'xyz' durch 'XYZ', aber nur die
                     'xyz' direkt an Zeilenenden.
                     (Spezielle Bedeutung von '^' und '$' !)
:g/ABC/s//CBA/g      Ersetzt in der ganzen Datei 'ABC' durch 'CBA'
:45,$g/ABC/s//CBA/g  Wie zuvor, jedoch erst ab Zeile 45.
:g/ABC/s//CBA/gp     Ersetzt in der ganzen Datei 'ABC' durch 'CBA'
                     (p = Zeilen dabei herzeigen)
                     (jeweils jedes Vorkommen in den Zeilen)
:g/ABC/s//CBA/gc     Ersetzt in der ganzen Datei 'ABC' durch 'CBA'
                     (jeweils jedes Vorkommen in den Zeilen)
                     (und mit Erlaubniseinholung jeweils)
                     (<Delete> bricht ab)
:g/QQQ/s/CBA/WWW/g   In allen Zeilen, in denen QQQ vorkommt, wird
                     jedes CBA durch WWW ersetzt.
:4,79g/QQ/s/CB/WW/c  dito, beschränkt auf Zeilen 4-79
:g/ABC/s//xx&&&yy/g  Macht überall aus 'ABC'  'xxABCABCABCyy',
                     '&' steht (rechts) für das, was links resultiert.
                     ABC (links) könnte auch /  *[^s]printf/ sein!
:g//s//~/gc          '~' wirkt wie '&', erinnert sich jedoch an den
                     Ersatztext (rechts), der zuvor eingesetzt wurde.
                     g//  setzt vorhergehendes Suchmuster ein.
:g/[^S]TUV/p         Alle Zeilen mit TUV aber nicht S davor werden
                     angezeigt.
:g/\<TUV/p           Alle Zeilen mit TUV, aber nur, wo TUV der Anfang
                     eines Wortes oder Zeilenanfang ist.
:g/TUV\>/p           Alle Zeilen mit TUV, aber nur, wo TUV das Ende
                     eines Wortes oder Zeilenende ist.
:/[abcf]xyz          Sucht xyz mit einem der Zeichen a,b,c oder f davor.
:/[a-h]xyz           Hier mit einem der Zeichen a bis h.
:/a[^bcd]z           Hier alle 'a?z', aber nicht abz, acz und adz.
:/[^A-Z]             Hier alle Zeichen, aber keine Großbuchstaben.
:/[h-k]*swq/         Hier kann das, was [] beschreibt, beliebig oft
                     vorkommen, also auch nullmal.
:/[h-k][h-k]*swq/    Hier kann das, was [] beschreibt, >=1mal vorkommen.
:/qas...sdd          Hier stehen die Punkte für drei beliebige Zeichen.
:g/[0-9][0-9].*XYZ/s//   XYZ/
                     Überall, wo zwei Zeichen '0-9''0-9' und danach
                     beliebige Zeichen (.) in beliebiger Menge (*)
                     stehen, gefolgt von 'XYZ',
                     kommt hin: '   XYZ'.
:g/^$/s/^M^M/        Wo vorher 1 Leerzeile war sind jetzt 3.   ('^M'!)
········································································
Spezial-Operatoren:   \(   \)   \1   \2  ...  \9
abcdefghijklm                                     steht in Zeile 178.
:178s/a\(bcd\(ef\)gh\)i/A\1B\1C\2\2\2\2D/         Dieses Kommando
AbcdefghBbcdefghCefefefefDjklm                    macht <-- daraus !
A  bcd  ef  gh  B bcd ef gh C ef ef ef ef D jklm
Das hat was mit 1. und 2. Klammerebene zu tun.        (bis 9 Ebenen)
Die Klammer-Paare müssen nicht verschachtelt sein.
Auch bei nebeneinander stehenden zählt die öffnende Klammer \(
jeweils um eins weiter:
FTp[ix++][2]; FTp[NFND][0]; FTp[ifno][1]; 
:g/FTp\[\(....\)\]\[\([012]\)\]/s//FTp[\2][\1]/g
FTp[2][ix++]; FTp[0][NFND]; FTp[1][ifno];   ist das Ergebnis.
········································································
ed und sed können auch:  s/\([^ ]\)\1\1\1/\1/g       (\1 linksstehend!)
Alle Zeichen !=' ' 4-fach-gleich z.B. 'AAAA' werden vereinzelt:==> 'A'.
Weiterhin:  \{n\}   \{n,\}   \{n,m\}   (?-mal 1-char-expr.)
········································································
:g/Hier/s//\UHier/   Macht aus Hier HIER. '\U' schaltet auf Uppercase.
:g/Hier/s//\U&/      dito !
:g/HIER/s//\Uh\LIER/ Macht aus HIER Hier. '\L' schaltet auf Lowercase.
                     '\u' und '\l' müssen von einem Buchstaben direkt
                     gefolgt werden, für den das dann gelten soll.
                     '\E' oder '\e' schaltet '\U' und '\L' ab.
········································································
Steuerzeichen:  ^, $, /, &, [, ], \, ., *, ~, ? 
Diese müssen -links stehend- mit \ maskiert werden. Das heißt, wenn
sie als normale Zeichen aufgefaßt werden sollen.  (also: '\$'='$', usw.)
(zwar nicht alle - aber sicher ist sicher!)
Für \, &, ~ und / gilt das auch rechts.
········································································
Mit  //  und  ??  kann man sich auf ein vorangegangenes Muster
beziehen.  Dabei ist das einzige oder aber das linke Muster gemeint.
Also  g//p  wiederholt g/abc/p oder auch andere Sequenzen mit /abc/.
------------------------------------------------------------------------
Bei Eingabefehlern (:asbw76@4#,) :  <Delete> oder mit <BackSp>
                                     zurück bis über ':' hinweg.
Bei dd z.B. kann man das erste d noch mit <Esc> löschen, wenn man
es sich anders überlegt hat.
------------------------------------------------------------------------

------------------------------------------------------------------------
:w     Bisherigen Zustand zur Festplatte schreiben.
       Die wirkliche aktuelle Datei wird (zwischendurch) aktualisiert.
       Quasi wie :x - jedoch ohne vi zu verlassen.
:w!    Bisherigen Zustand zur Festplatte schreiben.
       Überwindet Schreibschutz (Read only)!
:w b   Wenn Editor mit 'vi a' gestartet wurde, wird der Inhalt des
       vi-Puffers in b geschrieben, wobei b dazu erzeugt wird.
       Wenn nur mit 'vi' begonnen wurde, wird b erzeugt.
       Wenn b bereits existiert, gibt's eine Warnung!
:w! b  Wenn b bereits existiert, wird b überschrieben!
       Überwindet also Warnungen!
:w>>b  Hängt vi-Puffer-Inhalt an existierenden Datei-Inhalt von b an.
       (es darf auch ein Leerzeichen (Space) vor b stehen.)
:w !cmd         Schreibt Puffer-Inhalt zu einem UNIX-Kommando.
:160,175w b     Schreibt Puffer-Zeilen 160 bis 175 in b. (siehe ':w b')
:160,175w>>b    Schreibt Puffer-Zeilen 160 bis 175 ans Ende von b.
:160,175w !cmd  Schreibt Puffer-Zeilen 160 bis 175
                zu einem UNIX-Kommando.
:1,15w !more    BEISPIEL:  übergibt Zeilen 1 bis 15 an 'more'.
:160,185 !cmd   Übergibt die Zeilen an 'cmd', löscht diese Zeilen (!),
                und fügt die Ausgabe von 'cmd' dort ein.
                :50,70 !sort   sortiert die Zeilen 50 bis 70 !
                (Argumente und shell-metachars sind erlaubt)
:%!sort         Sortiert gesamten Pufferinhalt. (% = 1,$)
                Nach % kein Leerzeichen!
:160,185 !tr "m" "\234"               (PC8-Zeichensatz)
                Ersetzt von 160-185  'm' durch '£'   (siehe 'man tr')
········································································
:n     Zur nächsten Datei gehen   (bei mehreren gleichzeitig)
       (Gegenwärtige Einstellung macht vorher automatisch :w !)
:n!    Überwindet Warnungen, daß :w nicht benutzt wurde.
:n e f Bearbeitet eine neue Datei-Liste, bestehend aus den Dateien
       e und f.  Die alte Liste wird verlassen.
:args  Zeigt aktuelle Datei-Liste an, mit Markierung der gerade in
       Arbeit befindlichen.
       :n und :args haben zueinander Bezug, nicht jedoch mit :f (s.u.).
:rew   Geht zur ersten Datei in der args-Liste.
:rew!  Überwindet Warnungen, daß :w nicht benutzt wurde.
········································································
:e g   Eine andere Datei g wird editiert, ggf. zuvor erzeugt.
       Man kann zwar so zu beliebig vielen Dateien springen, aber
       der vi behält nur zwei gleichzeitig 'in sich'.
:e#    Springt zur vorherigen zurück, und wieder zurück, usw.
:e%    Bezieht sich auf die gegenwärtige (:f), löscht den ':e#'-Bezug,
       und liest die aktuelle Datei (:f) (neu) in den Puffer ein.
       Hat generell keinen Bezug zur :args-Liste mit 'a [b] c d ...'.
:e! g  Überwindet Warnungen, daß :w nicht benutzt wurde. (siehe :e g)
:f     Gibt Informationen über Datei
:f nn  Gibt aktuellem Pufferinhalt neuen Namen (nn), also einen anderen
       als den, mit dem man vi aufrief:  vi aaa ; jetzt: aaa --> nn
       Datei aaa existiert aber weiter, jedoch was ihren Inhalt
       angeht, bleibt dieser uneditiert, wenn nicht :w gemacht wurde,
       bevor :f nn  gegeben wurde  !
       Es ist also eine Übernahme des Inhalts von aaa in eine neue
       Datei nn hinein, um in dieser neuen weiterzueditieren.
       Und man muß den Puffer ausschreiben, damit nn auch existiert.
       Es sei denn, nn war vorher schon existent.
········································································
:r d   Holt angegebene Datei 'd' hinter aktuelle Zeile herein
:12r d Holt angegebene Datei 'd' hinter Zeile 12 herein
:0r d  Holt angegebene Datei 'd' an den Puffer-Anfang herein
:$r d  Holt angegebene Datei 'd' an das Puffer-Ende herein
       (Bei Start mit 'vi' und leerem Puffer editiert man dann quasi d.)
:r !cmd  Holt die Ausgabe eines UNIX-Kommandos hinter aktuelle Zeile.
BEISPIEL:  :$r !find . -print
           schreibt die von 'find' gefundenen Dateinamen im aktuellen
           Directory (.) an's Puffer-Ende.
!!cmd    Die Ausgabe eines UNIX-Kommandos ERSETZT die aktuelle Zeile.
3!!cmd   Die Ausgabe eines UNIX-Kommandos ERSETZT aktuelle +2 Zeilen.
!!cc -Zs %     Für % wird der aktuelle Dateiname eingesetzt.
------------------------------------------------------------------------

------------------------------------------------------------------------
vi         Startet vi-Editor nur im 'unsichtbaren' Puffer
vi d       Startet vi-Editor mit Datei d
vi a b c   Startet vi-Editor mit Dateien a, b und c  (siehe :n)
vi *.c     Startet vi-Editor mit allen c-Dateien im Directory
vi -R d    Startet vi-Editor mit Datei d und nur Lesen ist erlaubt
vi -L      Listet alle nach einem Crash gesicherten Dateien
vi -r f    Nach einem Crash kann man hiermit Datei f herholen.
           (siehe auch  :preserve  und  :recover)
vi -w10 f  Macht Fenster nur 10 Zeilen groß.
:!vi s     Startet vi nochmal aus vi heraus - als weiteren Prozeß !
:!cmd      Führt UNIX-Kommando 'cmd' aus   (z.B.:  :!cp engl.c /u/gabi)
           (Gegenwärtige Einstellung macht vorher automatisch :w !)
:!csh      Startet eine neue C-Shell.  Ende durch <Ctrl><d> oder 'exit'.
:!sh       Startet eine neue Bourne-Shell.  Ende wie oben.
:sh        Startet eine neue Shell.  (sh/csh/ksh gemäß :setall-shell)
:cd d      Wechselt das Directory nach d. (And. Wrkg. als bei ':!cd d')
········································································
:x     Editor beenden, mit Aktualisierung der 'echten' Datei.
ZZ     dito
:x a   Editor beenden, mit Puffer-Schreiben zur Datei a.
       (vi-Warnung, falls a existiert.)
:q     Editor beenden, ohne Änderungen zu berücksichtigen (vi-Warnung)
:q!    Editor beenden, ohne Änderungen zu berücksichtigen
       Überwindet Warnungen!
:wq    Wie :w  und dann :q  oder auch wie :x
:wq!   Wie :w! und dann :q. Überwindet auch 'Read only' (Nur lesen) !
:wq b  Wie ':w b'  und dann :q.                           (vi-Warnung)
:wq! b Wie ':w! b' und dann :q.                           (vi-Warnung)
Q      Geht in den ex-Editor bzw. zeilen-orientierten Modus;
:vi    geht wieder zum bildschirm-orientierten Modus zurück.
------------------------------------------------------------------------
:=          Zeigt aktuelle Anzahl Zeilen im Puffer an.
:nu         Zeigt aktuelle Zeile mit deren Nummer
:1,10nu     Zeigt Zeilen 1-10 mit deren Nummern
:preserve   Sichert Puffer in schlimmen Situationen
            (mail-Paket muß installiert sein!)
:recover d  Holt Datei d von dem Absicherungsbereich
········································································
:set all     Zeigt alle Einstell-Optionen, jedoch nicht die Abkürzungen
:set         Zeigt alle, die von der Standardeinstellung abweichen
:set ai?     Zeigt den Zustand von ai an
:set nonu    Schaltet Zeilen-Numerierung ab             (nonumber)
:set nu      Schaltet Zeilen-Numerierung ein              (number)
:set ai      Erzeugt automatische Absatz-Einfügung    (autoindent)
             Es werden Leerzeichen und Tabs eingefügt.
:set noai    Stellt wieder Normal ein               (noautoindent)
:set list    Macht Tabs und Zeilenenden sichtbar
:set nolist  ...
Siehe Datei /u/sc/.exrc (vi-Konfigurations-Datei): set, map, map!, abbr
:map @ A;^[
:map! oe ö   Schreibmodus-map!  Bei 2 Zeichen diese schnell drücken!
:unmap  ^T
:unmap! oe|ö
:unabbr vvv  Machen rückgängig.
Folgende Zeichen sind im Kommandomodus nicht belegt:
g q v K V ^A ^C ^K ^O ^Q ^T ^V ^W ^X ^Z (^=<Ctrl>)
- können also gemapt werden!
------------------------------------------------------------------------

AUTOR   Helmut Schellong, Bad Salzuflen



^

 bish(V)                                                                bish(V)



 NAME
      bish.mnv - Vergleichsbetrachtungen zum Shell-Programm bish



 BESCHREIBUNG
      Diese Datei vergleicht  bish  mit anderen Shell-Programmen.
      Dies erlaubt eine Eignungs- und Leistungsbeurteilung.

      |  Einordnung der bish
      |  Herkunft und Zielrichtung der bish
      |  Geschwindigkeits-Vergleiche  bish:ksh:zsh:bash:csh:sh:4dos.com




   Einordnung von  bish  unter andere Shell-Programme:
   ===================================================

      Umfang ^           bish+i
      Leistg.|                 zsh     [perl]
             |
             |                 ksh
             |                    bash                tcsh 
             |            bish
             |
             |                                            csh
             |
             |    sh 
             |                           4DOS.COM
             |
             |
             |
             |
             |            COMMAND.COM
             --------------------------------------------------------->
                                                              Ähnlichkeit
             []:Keine Shell, sondern reine Script-Sprache
             bish+i: inklusive aller internen Kommandos.

             Bezüglich der Arbeitsgeschwindigkeit ist die bish anderen
             Shells bis zu hundertefach überlegen - im Mittel glatt
             um 1000 Prozent!
             Deshalb und wegen der zahlreichen internen Kommandos
             ist die bish -insgesamt- das leistungsfähigste
             existierende Shell-Programm.




   Herkunft und Zielrichtung der bish:
   ===================================

      |-----------DOS-----------|
      |                         |
      |command.com --> 4dos.com <---Div.
      |                ndos.com |        |------UNIX-------|
      |                         |        |                 |
      |        bish.exe  <----------------- ksh <-- sh     |
      |                         |    |   |  zsh, bash; perl|
      |-------------------------|    |   |  tcsh <-- csh   |
                                     |   |  bish           |
         OS/2   bish     <-----------|   |---|-------------|
         W-NT   bish     <-----------|       |
                                     ---->---|

   Die bish holt die mächtigste Script-Sprache nach DOS, wo standardmäßig
   das Gegenteil, nämlich die einfachste Script-Sprache vorhanden ist.
   Dazwischen liegen OS/2 und Windows-NT.




   Geschwindigkeits-Vergleiche   bish:ksh:zsh:bash:csh:sh:4dos.com
   ===============================================================

   Die folgenden Messungen wurden unter gleichen Bedingungen vorgenommen.
   Zugehörige Shell-Scripts -die Meßobjekte- folgen nach den Zeitwerten.

   Diese Zeitvergleiche sind insbesondere deshalb aufgeführt, weil die
   bish derartig schnell ist, daß man fast von "interpreter-untypisch"
   sprechen darf und daher mit der bish Aufgaben angehen kann, die man
   normalerweise nicht mit Shell-Programmen erledigt.
   Zu Zeiten, wo der Vorsprung neuer Prozessorgenerationen zumeist doch
   unterhalb von 100 Prozent liegt, sind Geschwindigkeitsunterschiede
   von 1000 Prozent und (viel) mehr von sehr erheblicher Bedeutung.

   Unter insgesamt 7 getesteten Shells war bisher nur eine, die ungefähr
   so schnell ist wie die bish, und zwar die ksh unter SCO-Unix.
   Ihre Arithmetik und Programmablaufsteuerung arbeiten bei kleinen Ausdrücken
   fast so schnell wie die der bish.
   ---
   Ein Vorabnachteil der bish hinsichtlich Tempo ist ihre totale Portabilität.
   Sie ist auch für DOS konzipiert, arbeitet stark datei-orientiert, ist
   ein ganz 'reiner' Interpreter und hat keine compiler-ähnlichen Arbeits=
   weisen, wie sie andeutungsweise/möglicherweise diese ksh hat.
   Die bish muß auch mehr Kommandonamen suchen - das kostet Zeit.
   Ein Schwerpunkt der bish sind die zahlreichen internen, echten
   Arbeits-Kommandos.
   Trotz all dieser Erschwernisse ist die bish die schnellste Shell.

   Geschwindigkeitsunterschiede bis etwa 70% sind allerdings unerheblich.
   Es geht hier darum, aufzuzeigen, daß die bish -und auch diese ksh-
   dutzendfach und mehr schneller sind als die anderen Shells ... !
   Es wurde mehrere hundertfach(!!!) höherer Zeitbedarf festgestellt.
   Ob ein Skript 3 Sekunden oder zehn Minuten läuft - das ist schon wichtig!
   bish und SCO-ksh  hängen auch die modernen  zsh und bash  ungefähr um
   einen Faktor 10-20 ab.

   Gemessen wurde unter UNIX - wenn nicht anders angegeben.
   Unter DOS ist bish meistens um 15-45 Prozent langsamer,
   in Spezialfällen um einen Faktor 30-50 (System!) langsamer.
   Als Hardware wurde ein Pentium60-PC benutzt.

   ======================================================================
    T A B E L L E   über Arbeitstempo und zugehörige Zeitfaktoren
   ======================================================================
    bish   ************************************************************
    ksh    *******************************************
    zsh    *****
    bash   ***
    csh    **
    4dos   *
    sh     -
   ----------------------------------------------------------------------
    Script      bish     ksh     zsh     bash     csh     sh    4dos.com
   ----------------------------------------------------------------------
    loop        1       1.11    11.4    19.4     39.0    205.    37.2
    loop        1       1.07     9.1    19.3     30.6     33.9   27.0
    s70         1       1.64    12.9    ----     29.3    265.    52.2
    s70         1       1.64    12.7    ----     29.1     51.8   47.2
   ----------------------------------------------------------------------
    bish und SCO-ksh verweisen alle anderen auf die Plätze!
   ----------------------------------------------------------------------
    Celeron366:    bish:  0.055  (loop)
                   ksh :  0.085  (loop)


     timex  bish -p loop.bish        # bish
     9000                            # Ausgabe des Scripts
                                     # Ausgabe des Zeitnahme-Kommandos:
     real        0.73                # 1.0    (Zeitfaktor)
     user        0.70                # 1.0    (Zeitfaktor)
     sys         0.03
     real        0.99                # 1.0    timex-Messung unter DOS

     timex  ksh -p loop.ksh          # ksh (SCO-Unix)
     9000
     real        0.81                # 1.11   (Zeitfaktor)
     user        0.75                # 1.07   (Zeitfaktor)
     sys         0.06         

     timex  zsh    loop.ksh          # zsh (GNU)
     9000
     real        8.29                # 11.4   (Zeitfaktor)
     user        6.35                # 9.07   (Zeitfaktor)
     sys         1.94         

     timex  bash   loop.ksh          # bash (BourneAgainShell)
     9000
     real       14.19                # 19.4   (Zeitfaktor)
     user       13.54                # 19.3   (Zeitfaktor)
     sys         0.65         

     timex  csh -f loop.csh          # csh
     9000
     real       28.44                # 39.0   (Zeitfaktor)
     user       21.44                # 30.6   (Zeitfaktor)
     sys         6.99

     timex  sh     loop.sh           # sh (Bourne-Shell)
     9000
     real     2:29.76                # 205    (Zeitfaktor)
     user       23.72                # 33.9   (Zeitfaktor)
     sys      1:57.06

     timex  4dos /c loop.bat         # 4dos.com ; Messung unter DOS!
     9000
     real       36.80                # 37.2   (Zeitfaktor) = 36.8/0.99
     timex  4dos /c loop.btm         # 4dos.com ; Messung unter DOS!
     real       26.75                # 27.0   (Zeitfaktor) = 26.75/0.99


     timex bish -p s70.bish 1111111111 # bish
       Fr, 18.3.2005  1:58:31        # Ausgabe des Scripts
     real        0.014               # 1.0    (10xMessung)
     user        0.011               # 1.0
     sys         0.003
     real        0.022               # timex-Messung unter DOS

     timex ksh -p s70.ksh 1111111111 # ksh (SCO-Unix)
       Fr, 18.3.2005  1:58:31        # Ausgabe des Scripts
     real        0.023               # 1.64   (10xMessung)
     user        0.018               # 1.64
     sys         0.006

     timex zsh    s70.ksh 1111111111 # zsh (GNU)
       Do, 18.4.2005  1:58:0         # Ausgabe des Scripts
     real        0.18                # 12.9
     user        0.14                # 12.7
     sys         0.04 

     timex csh -f s70.csh 1111111111 # csh
       Fr, 18.3.2005  1:58:31
     real        0.41                # 29.3
     user        0.32                # 29.1
     sys         0.04

     timex sh     s70.sh  1111111111 # sh
       Fr, 18.3.2005  1:58:31
     real        3.71                # 265-mal langsamer!
     user        0.57                # 51.8   (haupts.wg. `expr ...`)
     sys         3.01                # Haupts.wg. expr=externes Kommando.

     timex 4dos /E:2000 /C s70.bat 1111111111
     "  Fr, 18.3.2005  1:58:31"      # Ausgabe des Scripts
     real        1.148               # 52.2   (10xMessung unter DOS)
     timex 4dos /E:2000 /C s70.btm 1111111111
     "  Fr, 18.3.2005  1:58:31"      # Ausgabe des Scripts
     real        1.038               # 47.2   (10xMessung unter DOS)

     timex ksh -p s70.sh  1111111111 # ksh: s70.sh  !!!
       Fr, 18.3.2005  1:58:31
     real        6.33                # 452 
     user        1.66                # 151    (haupts.wg. `expr ...`)
     sys         4.63                # Haupts.wg. expr=externes Kommando.

   Für die vorstehenden Zeitmessungen wurden Scripts verwendet, die sich
   möglichst wenig an das System wenden, denn es sollten die Shells selbst
   verglichen werden und nicht die Systemdienste.
   Folgendes Beispiel zeigt, daß die Systemfunktionen und/oder das DOS-System
   zumindest bei doppelter Umlenkung ganz außerordentlich langsam sind.
   Datei = 100KB:
        DOS:      tr abc ABC < Datei > DateiUC     :     4.78 sec
        UNIX:     tr abc ABC < Datei > DateiUC     :     0.10 sec
   Bei Dateizugriffen ohne Umlenkung gibt es kaum Unterschiede.



 #:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
   #loop.bish
   typeset -i10 A
   for A to 10000 repeat
   do
     (( A==9000 )) && echo $A
   done
 #-----------------------------------------------------------------------

 #:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
   #loop.csh
   @ A = 1
   while ( $A <= 10000 )
      if ( $A == 9000 )  echo $A
      @ A++
   end
 #-----------------------------------------------------------------------

 #:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
   #loop.ksh
   typeset -i10 A=1
   while (( A<=10000 ))
   do
     (( A==9000 )) && echo $A
     ((A+=1))
   done
 #-----------------------------------------------------------------------

 #:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
   #loop.sh
   A=1
   while [ $A -le 10000 ]
   do
     test $A -eq 9000 && echo $A
     A=`expr $A + 1`
   done
 #-----------------------------------------------------------------------

 #:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
   REM loop.bat/loop.btm:4dos.com
   @echo off
   do A = 1 to 10000
     if %A eq 9000  echo %A
   enddo
 #-----------------------------------------------------------------------


   Die folgenden fünf Shell-Scripts erzeugen Wochentag, Datum und Uhrzeit
   aufgrund einer Zeitangabe in Anzahl Sekunden.
   Sie sind Grundlage für obenstehende Zeitmeßwerte.


 #:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
#!/u/bin/bish
[ $# -lt 1 ] &&  echo "  Argument:  Sekunden seit 1.1.1970 00:00:00"
[ $# -lt 1 ] &&  exit 1
[ "$1" = -h ] && echo "  Argument:  Sekunden seit 1.1.1970 00:00:00" &&
                 exit

typeset -i10 corr j sec SPT m cjsj
typeset -i10 tm_mday tm_hour tm_min tm_wday tm_sec tm_mon tm_year

sec=$1
((SPT=24*3600))
array MA  $SPT $SPT $SPT $SPT $SPT $SPT $SPT $SPT $SPT $SPT $SPT $SPT
(( MA1*=31, MA2*=28, MA3*=31,
   MA4*=30, MA5*=31, MA6*=30,
   MA7*=31, MA8*=31, MA9*=30,
   MA10*=31, MA11*=30, MA12*=31
))
#MA[1]*=31, etc., ist auch möglich

array WA  So Mo Di Mi Do Fr Sa

j=1970
repeat
do
   (( cjsj=0,
      corr= SPT*365 + (j%4==0&&j%100||j%400==0 ? (++cjsj,SPT) : 0),
      sec<corr )) && break
   (( sec-=corr, ++j ))
done

m=1
repeat
do
   array corr=MA m
   (( corr+= m==2&&cjsj ? SPT : 0, sec<corr )) && break
   (( sec-=corr, ++m ))
done

(( tm_mday=sec/SPT+1, sec%=SPT,
   tm_hour=sec/3600, sec%=3600, tm_min=sec/60, sec%=60
))
let "tm_wday=( $1 %% (SPT*7) )/SPT+4"              #1.1.1970=Do=4
(( tm_wday-= tm_wday>6?7:0, ++tm_wday ))

tm_sec=$sec  tm_mon=$m  tm_year=$j
# tm_yday=0 tm_isdst=0

array WAwd=WA $tm_wday
echo "  $WAwd, $tm_mday.$tm_mon.$tm_year  $tm_hour:$tm_min:$tm_sec"
 #-----------------------------------------------------------------------


 #:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
#!/bin/csh
#s70.csh
if ( $#argv < 1 )  echo "  Argument:  Sekunden seit 1.1.1970 00:00:00"
if ( $#argv < 1 )  exit (1)
if ($argv[1] == -h) then
  echo "  Argument:  Sekunden seit 1.1.1970 00:00:00" ; exit
endif
#
set  sec=$1
@ SPT = 24 * 3600
set MA=($SPT $SPT $SPT $SPT $SPT $SPT $SPT $SPT $SPT $SPT $SPT $SPT)
@ MA[1] *= 31 ; @ MA[2] *= 28 ; @ MA[3] *= 31 ;
@ MA[4] *= 30 ; @ MA[5] *= 31 ; @ MA[6] *= 30 ;
@ MA[7] *= 31 ; @ MA[8] *= 31 ; @ MA[9] *= 30 ;
@ MA[10] *= 31 ; @ MA[11] *= 30 ; @ MA[12] *= 31 ;
set WA=(So Mo Di Mi Do Fr Sa)
#
@ j = 1970
while ( 1 )
   @ cjsj = 0
   if ( ! ($j % 4) && ($j % 100) || ! ($j % 400) )  @ cjsj = 1
   @ corr = $SPT * 365
   if ( $cjsj )  @ corr += $SPT
   if ( $sec < $corr )  break
   @ sec -= $corr
   @ j++
end
@ m = 1
while ( 1 )
   @ corr = $MA[$m]
   if ( $m == 2 && $cjsj )  @ corr += $SPT
   if ( $sec < $corr )  break
   @ sec -= $corr
   @ m++
end
#
@ tm_mday = $sec / $SPT + 1
@ sec %= $SPT
@ tm_hour = $sec / 3600
@ sec %= 3600
@ tm_min = $sec / 60
@ sec %= 60
#
@ tm_wday = ($1 % ($SPT * 7)) / $SPT + 4           #1.1.1970=Do=4
if ($tm_wday > 6)  @ tm_wday -= 7
@ tm_wday++
#
@ tm_sec = $sec ; @ tm_mon = $m ; @ tm_year = $j
# @ tm_yday = 0 ; @ tm_isdst = 0
#
echo "  $WA[$tm_wday], $tm_mday.$tm_mon.$tm_year  ${tm_hour}:${tm_min}:$tm_sec"
 #-----------------------------------------------------------------------


 #:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
#!/bin/ksh
[[ $# -lt 1 ]] &&  echo "  Argument:  Sekunden seit 1.1.1970 00:00:00"
[[ $# -lt 1 ]] &&  exit 1
[[ "$1" = -h ]] && echo "  Argument:  Sekunden seit 1.1.1970 00:00:00" &&
                 exit

typeset -i10 corr=0 j=0 sec=0 SPT=0 m=0 cjsj=0
typeset -i10 tm_mday tm_hour tm_min tm_wday tm_sec tm_mon tm_year

sec=$1
((SPT=24*3600))
set -A MA  1 $SPT $SPT $SPT $SPT $SPT $SPT $SPT $SPT $SPT $SPT $SPT $SPT $SPT
(( MA[1]*=31 )) ; (( MA[2]*=28 )) ; (( MA[3]*=31 ))
(( MA[4]*=30 )) ; (( MA[5]*=31 )) ; (( MA[6]*=30 ))
(( MA[7]*=31 )) ; (( MA[8]*=31 )) ; (( MA[9]*=30 ))
(( MA[10]*=31 )) ; (( MA[11]*=30 )) ; (( MA[12]*=31 ))

j=1970
while :
do
   cjsj=0
   (( j%4==0 && j%100 || j%400==0 )) && cjsj=1
   ((corr=SPT*365))
   (( cjsj>0 ))  &&  ((corr+=SPT))
   (( sec<corr ))  &&  break
   ((sec-=corr)) ; ((j+=1))
done

m=1
while :
do
   corr=${MA[$m]}
   (( m==2 && cjsj )) && (( corr+=SPT ))
   (( sec<corr )) && break
   (( sec-=corr )) ; (( m+=1 ))
done

(( tm_mday=sec/SPT+1 )) ; (( sec%=SPT ))
(( tm_hour=sec/3600 )) ; (( sec%=3600 )) 
(( tm_min=sec/60 )) ; (( sec%=60 ))
let "tm_wday=( $1 % (SPT*7) )/SPT+4"              #1.1.1970=Do=4
(( $tm_wday>6 ))  &&  (( tm_wday-=7 ))
(( tm_wday+=1 ))

tm_sec=$sec  tm_mon=$m  tm_year=$j
# tm_yday=0 tm_isdst=0

set -A WTA  sa so Mo Di Mi Do Fr Sa So
WAwd=${WTA[$tm_wday]}
echo "  $WAwd, $tm_mday.$tm_mon.$tm_year  $tm_hour:$tm_min:$tm_sec"


 #-----------------------------------------------------------------------


 #:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
#!/bin/sh
#s70.sh
[ $# -lt 1 ] &&  echo "  Argument:  Sekunden seit 1.1.1970 00:00:00"
[ $# -lt 1 ] &&  exit 1
[ "$1" = -h ] && echo "  Argument:  Sekunden seit 1.1.1970 00:00:00" &&
                 exit

sec=$1
SPT=`expr 24 '*' 3600`
MA1=$SPT MA2=$SPT MA3=$SPT MA4=$SPT MA5=$SPT MA6=$SPT
MA7=$SPT MA8=$SPT MA9=$SPT MA10=$SPT MA11=$SPT MA12=$SPT
MA1=`expr $MA1 '*' 31`; MA2=`expr $MA2 '*' 28`; MA3=`expr $MA3 '*' 31`
MA4=`expr $MA4 '*' 30`; MA5=`expr $MA5 '*' 31`; MA6=`expr $MA6 '*' 30`
MA7=`expr $MA7 '*' 31`; MA8=`expr $MA8 '*' 31`; MA9=`expr $MA9 '*' 30`
MA10=`expr $MA10 '*' 31`;MA11=`expr $MA11 '*' 30`;MA12=`expr $MA12 '*' 31`
WA1=So WA2=Mo WA3=Di WA4=Mi WA5=Do WA6=Fr WA7=Sa

j=1970
while :
do
   cjsj=0
   [ `expr $j % 4` -eq 0 -a `expr $j % 100` -ne 0 -o `expr $j % 400` -eq 0 ] && cjsj=1
   corr=`expr $SPT '*' 365`
   [ $cjsj -gt 0 ]  &&  corr=`expr $corr + $SPT`
   [ $sec -lt $corr ]  &&  break
   sec=`expr $sec - $corr`; j=`expr $j + 1`
done
m=1
while :
do
   eval 'corr=$MA'$m
   [ $m -eq 2 -a $cjsj -ne 0 ] && corr=`expr $corr + $SPT`
   [ $sec -lt $corr ] && break
   sec=`expr $sec - $corr` ; m=`expr $m + 1`
done

tm_mday=`expr $sec / $SPT + 1` ; sec=`expr $sec % $SPT`
tm_hour=`expr $sec / 3600` ; sec=`expr $sec % 3600`
tm_min=`expr $sec / 60` ; sec=`expr $sec % 60`

tm_wday=`expr \( $1 % \( $SPT \* 7 \) \) / $SPT + 4`    #1.1.1970=Do=4
[ $tm_wday -gt 6 ]  &&  tm_wday=`expr $tm_wday - 7`
tm_wday=`expr $tm_wday + 1`

tm_sec=$sec  tm_mon=$m  tm_year=$j
# tm_yday=0 tm_isdst=0

eval 'WAwd=$WA'$tm_wday
echo "  $WAwd, $tm_mday.$tm_mon.$tm_year  $tm_hour:$tm_min:$tm_sec"
 #-----------------------------------------------------------------------


 #:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
@echo off
Rem 4dos.com
Rem loadbtm on
if %# LT 1  (echo "  Argument:  Sekunden seit 1.1.1970 00:00:00" ^ exit 1)
if "%1"=="-h"  (echo "  Argument:  Sekunden seit 1.1.1970 00:00:00" ^ exit)
setdos /F0.0

set corr=0 ^ set j=0 ^ set sec=0 ^ set SPT=0 ^ set m=0 ^ set cjsj=0
set tm_mday=0 ^ set tm_hour=0 ^ set tm_min=0 ^ set tm_wday=0
set tm_sec=0 ^ set tm_mon=0 ^ set tm_year=0

do 10

set sec=%1
set SPT=%@eval[24*3600]

set MA1=%@eval[%SPT * 31] ^ set MA2=%@eval[%SPT * 28]
set MA3=%@eval[%SPT * 31] ^ set MA4=%@eval[%SPT * 30]
set MA5=%@eval[%SPT * 31] ^ set MA6=%@eval[%SPT * 30]
set MA7=%@eval[%SPT * 31] ^ set MA8=%@eval[%SPT * 31]
set MA9=%@eval[%SPT * 30] ^ set MA10=%@eval[%SPT * 31]
set MA11=%@eval[%SPT * 30] ^ set MA12=%@eval[%SPT * 31]

set WA1=So ^ set WA2=Mo ^ set WA3=Di ^ set WA4=Mi
set WA5=Do ^ set WA6=Fr ^ set WA7=Sa

set j=1970
do forever
   set cjsj=0 
   if %@eval[%j %% 4] EQ 0 .AND. %@eval[%j %% 100] NE 0  set cjsj=1
   if %@eval[%j %% 400] EQ 0  set cjsj=1
   set corr=%@eval[%SPT * 365 + %cjsj * %SPT]
   if %sec LT %corr  leave
   set sec=%@eval[%sec - %corr] ^ set j=%@inc[%j]
enddo

Rem array corr=MA m
set m=1
do forever
   set corr=%[MA%m]
   if %m EQ 2 .AND. %cjsj NE 0  set corr=%@eval[%corr + %SPT]
   if %sec LT %corr  leave
   set sec=%@eval[%sec - %corr] ^ set m=%@inc[%m]
enddo

set tm_mday=%@eval[%sec \ %SPT + 1] ^ set sec=%@eval[%sec %% %SPT]
set tm_hour=%@eval[%sec \ 3600]     ^ set sec=%@eval[%sec %% 3600]
set tm_min=%@eval[%sec \ 60]        ^ set sec=%@eval[%sec %% 60]

set tm_wday=%@eval[ ( %1 %% (%SPT * 7) ) \ %SPT + 4]
Rem 1.1.1970=Do=4
if %tm_wday GT 6  set tm_wday=%@eval[ %tm_wday - 7 ]
set tm_wday=%@inc[%tm_wday]

set tm_sec=%sec ^ set tm_mon=%m ^ set tm_year=%j
Rem tm_yday=0 tm_isdst=0

set WAwd=%[WA%tm_wday]
echo "  %WAwd, %tm_mday.%tm_mon.%tm_year  %tm_hour:%tm_min:%tm_sec"

enddo
 #-----------------------------------------------------------------------




 AUTOR
      Helmut Schellong, Bad Salzuflen