CMS PIPE

Készítette: Budai Benjámin, Laudon Krisztina, Manhertz Tamás

Bevezetés

A CMS PIPE-ok nem egy külön programozási nyelv, hanem egy nagyon hatékony segédeszköz, amit a CMS REXX nyelvben rendkívül elonyösen lehet használni. Ez egy programmodul, aminek paraméterezésével olyan feladatokat lehet megoldani, amit hagyományos programozási nyelvek esetén csak nagy, egymásba ágyazott ciklusokkal lehetne, így is elpazarolva rengeteg programozói idot. A PIPE egy új technika a hagyományos REXX eljárásnyelv kiterjesztéséhez, mely egyben egy teljesen új gondolkodásmódot is igényel (ún. folyasztásos gondolkodást). A PIPE keszitoi nagyon jól megoldották ennek az eszköznek a REXX-be való integrálását, mint ahogy azt a késobbiekben láthatjuk.

A CMS csövek nagyon hasonlítanak a UNIX-ból ismerthez, bár vannak eltérések. A csöveket valamilyen adatfolyam feldolgozására lehet használni. Egy csõ egyrészt csõvezetékekbõl (pipeline), másrészt feldolgozó állomásokból (stage) áll. A csõvezetékekben folyik az adat, és az állomásokon lehet feldolgozni az éppen beérkezõ adatokat. Ez olyan mint egy gyárban a futószalag: maga a szalag a pipeline, a szalag elõtt alló munkás vagy automata pedig a stage. A munkadarab (itt adat) a szalagon megérkezik a munkáshoz, az elvégez rajta egy mūveletet, és a szalag tovább viszi a következõ munkáshoz, aki megint csinál vele valamit s.i.t. Az egész csõ egy párhuzamos adatfeldolgozó rendszer (ún. adatcsatorna).

Egy csõvezetéket az egymást követõ állomások, vagyis stage parancsok sorozatával kell megadni. Vannak olvasó, író, szūrõ és egyéb stage parancsok, és a felhasználó is írhat REXX-ben újakat. Egy állomásra az adatok rekordonként érkeznek, és így is mennek tovább. (Ugyanis a nagyszámítógépeken a file rendszer vagy a dataset-ek mindig rekordokbol épülnek fel, így értelmetlen is lenne a byte orientált stream bemenet.) Amikor a csõvezeték elejére rákerül egy adat, akkor az alapértelmezésben teljes hosszában lefoglalja a pipeline-t. Az egyes stage parancsok vagy pufferelik, vagy nem pufferelik az inputot. Pl. egy SORT (rendezés mūvelet) pufferel, mert az összes rekordot csak úgy lehet lerendezni, hogy elõbb be kell olvasni mindet.

A CMS PIPE-ok nagy elõnye már látszik az eddigiekbõl is, de még eleddig csak egy speciális esetrõl beszéltünk, arról, amikor csak egy csõvezetéket adtunk meg. A PIPE-ok igazi nagy elõnye akkor mutatkozik meg, ha mar több, egymással párhuzamos csõvezetéket építünk fel, melyek természetesen párhuzamosan is képesek mūködni. (Ezt a PIPE parancsmodul saját belsõ ütemezõje végzi el, ugyanis a CMS alapesetben nem multitaskos.) Ebben az esetben a csõvezetékek ráadásul még egymásba is futtathatók, illetve bárhol többfelé szétágaztathatók. Tehát például egy válogató stage parancsnál (LOCATE, FIND) az eredeti csõvezetéken továbbküldi azokat a rekordokat, melyek a szūrési kritériumnak megfelelnek és minden más rekordot pedig az esetlegesen leágaztatott további csõvezetékeken küldi tovább. Természetesen ilyenkor már figyelni kell arra, hogy a szét-, illetve összeágaztatott csõvezetékeket szinkronba hozzuk a rajtuk folyó adatrekordok tekintetében, ezért a legtöbb helyen meg lehet adni, hogy egy stage parancs mennyit késleltessen (hány rekordot puffereljen.) Ilyen késleltetett stage után be lehet ágaztatni egy másik csõvezetéket, és amíg a stage késleltet, addig a másik vezetéken jöhet az adat. A nem késleltetett stage parancsok után nem lehet beágaztatni másik pipeline-t.

CMS-ben egy csõrendszert a következõ alakban lehet megadni:

 PIPE (opciók) pipelines
Egy pipeline pedig stage parancsok megfelelõ összekapcsolása:
 stage cmd1 ] stage cmd2 ] ... ] stage cmdN
A stage parancsokat ] választja el, de megadható más szeparátor is: ehhez a (SEP szeparátor) opciót kell megadni. A PIPE parancsban szereplõ csõvezetékeket egy másik szeparátorral kell elválasztani; ez általában a ? szokott lenni, de ezt is át lehet definiálni a (END lezáró jel) opció megadásával. Bõvebben nem érdemes beszelni az opciókról.

A Stage parancsok (állomások) a következõ legfontosabb csoportokba sorolhatók:

Természetesen nem érdemes minden mūveletrõl részletesen beszelni, ugyanis egyrészt elegendõ az egyes csoportokat áttekinteni, másrészt a stage parancsok száma 100-on felül van, így tulajdonképpen egy könyv kerete lenne csak megfelelõ ennek a tárgyalására.

Input/Output mūveletek:

Ide tartoznak a file mūveletek, melyeket a CMS PIPE is a <, illetve a > jelekkel ad meg. Ebbe a csoportba tartozik meg pl a CONSOLE, mely a beérkezõ rekordokat a terminálra írja ki, a READER, PUNCHER kezelésére vonatkozó stage parancsok.

Elemi adatok:

Elemi adatok is (közvetlen rekordok) megadhatók a pipeline során szinte Bármelyik állomáson. Ide tartozik pl. a LITERAL, STRLITERAL stage parancsok, melyek paraméterei jelentik a rekordot, amit az adatstreamhez hozzáfuznek (ami lehet persze üres is).

Szurés:

Az ebbe a csoportba tartozó stage parancsok nagyon valtozatos mūködesre kepesek, és tulajdonképpen minden megoldható velük, amit a rekordokkal el lehet végezni. Képesek egy csõvezetéken és egyszerre (puffereléssel) több csõvezetéken is mūködni. Ide tartozik például a már említett LOCATE vagy FIND stage parancsok, melyek bizonyos szempontok szerint képesek szövegesen keresni a beérkezõ rekordok között. Vannak olyanok, melyek az elsõ vagy utolsó elofordulást keresik, és onnan, illetve addig engedik tovább az adatrekordokat, vagy a paraméterezésben megadott darabszámú rekordokat dobjak el vagy engedik tovább. Meg számos szūrõ stage parancs létezik, ezek pontos szintaktikáját is a CMS HELP tartalmazza.

Adatok formázása:

A PIPE a rekordokat alapjában véve szöveges rekordoknak értelmezi. Persze ez nem zárja ki bináris adatok feldolgozását, hiszen pl arra is létezik stage parancs, hogy adott bináris értékeket egy táblázat szerint átkódol. &IACUTE;gy nagyon könnyen lehet bármilyen kódoló csöveket készíteni.

A szövegek feldolgozásának egyik alapeleme a megfelelõ formázás. Ez azt jelenti, Hogy képes legyen tetszõlegesen átvagdosni a rekordot, beszúrni új elemeket, rekordokat egyesíteni tetszõleges sorrendben, formátumban, rekordokat darabolni, egyesíteni, és mindezt persze multistream-ekre is képes legyen elvégezni. A példákban részletesebben kitérünk az ilyen jellegu formázó stage parancsokra.

Kapcsolat az operációs rendszerrel:

Többféle kapcsolati módozatot támogat a CMS PIPE. Egyrészt adható közvetlen parancs a CMS, illetve a CP számára (a VM operációs rendszer két szintje), valamint megoldották az egyes virtuális gépek közötti kommunikációját is. Erre is kétféle lehetõséget ad, a VMCF (Virtual Machine Communication Facility), illetve az IUCV (Inter-User Communication Vehicle). Az utóbbi használata jobban elterjedt, mivel ez a módszer a CPU által követlen utasítással van támogatva, másrészt a virtuális gép bizonyos, a CP által szolgáltatott adatait, információit lehet ez által megszerezni. Mivel az IUCV mūködése meglehetõsen összetett, így ezen dokumentáció kereteit meghaladja, a példákban elsõsorban az operációs rendszer parancsokkal való vezérlését mutatjuk be.

Még ide tartoznak azok a stage parancsok is, melyek a REXX eljárásnyelv felé adnak interface-t. Ilyen lehet maga a REXX stage parancs, mellyel egy REXX program hívható meg végrehajtásra (errõl még bõvebben is lesz szó), illetve az olyan stage parancsok, melyekkel REXX változók értékei manipulálhatok (pl. VAR, STEM).

Több pipeline vezérlése:

Nem kimondottan vezérlésrõl van szó, hanem inkább olyan stage parancsokról, melyek képesek egyesíteni, szétágaztatni bizonyos szempontok szerint a csõvezetéket. Ilyen például a FANIN, FANOUT stage parancsok, melyek több pipeline adatcsatornáját képesek összekötni, azzal együtt, hogy melyiket rakja a másik elé, illetve a bemeneti adatcsatornát többfele szétágaztatni úgy, hogy mindenhová ugyanazt küldi. Ebbe a kategóriába továbbá még a szuro, illetve adatformázó stage parancsok is beletartoznak, mert szinte mindegyike képes multistream-ekkel is mūködni. Példának már megemlítettük a LOCATE parancsot, melyhez hasonlóan kezelodik a többi esetben is a pipeline.

Speciális mūveletek:

Vannak viszonylag összetett mūködéssel rendelkezo stage parancsok. Ilyenek például a rendezés, multistream-es válogatás, különbözõ forrásszövegek, listafile-ok kezelésére specializált stage parancsok (persze ezeken kívül még számtalan létezik). A rendezés több szempont szerint is történhet, a multistream-es válogatás pedig a módszertani szempontból fontos elemenkénti feldolgozás egyik speciális esete (2,3). Erre a legutolsó példában még visszatérünk.

REXX Interface:

A CMS PIPE rendkívül jól illeszthetõ össze a REXX eljárásnyelv elemeivel. Mint ahogy volt is szó róla, lehetséges stage parancsokkal REXX program változóinak a kezelésére. Ez azt jelenti, hogy pl a STEM stage paranccsal a beérkezõ rekordokat a STEM paraméterében megadott nevū REXX tömbváltozóba helyezi, majd a PIPE befejezõdése után a REXX tömb használható. Hasonló a VAR stage is, de itt csak egy rekord (az utolsó) kerül elhelyezésre a változóban.

Természetesen a REXX és a PIPE kicsit szorosabban fūzõdik egymáshoz, mint a változókon keresztüli kommunikáció. Létezik a REXX nevū stage parancs, mely paramétere egy REXX eljárásnyelvben megírt file. Ekkor a pipeline megfelelõ helyén a beáramló rekordok átadásra kerülnek a REXX programnak, ahol hagyományos módon bármilyen feldolgozáson keresztül eshet, majd tovább is adhat rekordokat a pipeline következõ állomásának. Ezt a PIPE speciális REXX utasításokkal támogatja, mellyel tulajdonkeppen kibõvíttette magát a nyelvet. Ilyen utasítás a "READTO ", mely a stage bemenetérõl olvas be egy rekordot. Ennek ellentéte az "OUTPUT ", mely a stage kimenetére helyezi a megadott rekordot.

Van egy érdekessége ennek az interface-nek. Mivel a REXX programon belül hívhatunk CMS PIPE-okat, és viszont, ezért lehetõseg van a PIPE-ok rekurzív módon való egymásba ágyazásába is. Tehát például egy PIPE-ból hívott REXX programban nyugodtan hívhatunk újabb PIPE-okat (de ekkor mar csak a CALLPIPE kulcsszóval), melyek akár minden rekordra külön-külön is tudnak mūködni. PIPE-on belül is hívhatunk alcsöveket, ezt is a CALLPIPE stage paranccsal tehetjük meg. Ekkor a CALLPIPE stage parancsnál minden rekordra meghívódik az ott definiált PIPE rendszer, ahol aztán tovább folytathatjuk a hívások sorát.

Látható, hogy ettõl jobban már kevésbé lehetne általánosítani az adatcsatornás feldolgozási módszert.


Néhány konkrét példa:

1)
 PIPE < A A A ] TAKE 9 ] CONSOLE
Itt a < jel az olvasó stage parancs. Utána meg kell adni az input file nevét, ami itt most A A A. A következõ stage parancs a TAKE n, ami n sort olvas, majd kilep. Végül az eredmény a konzolra íródik. A fenti parancs tehát az A A A file elsõ 9 sorát írja ki a terminálra.

2)

 PIPE < A A A ] SORT ] TAKE LAST 9 ] CONSOLE
Itt beiktattunk egy SORT parancsot, ami rendezi a bejövo rekordokat, majd tovább küldi oket a TAKE-nek. A TAKE után a LAST 9 most azt mondja meg, hogy nem az elsõ 9, hanem az utolsó 9 rekord menjen csak tovább.

3)

 PIPE < A A A ] SORT ] DROP 10 ] CONSOLE
A TAKE helyett DROP van, ami azt mondja, hogy a file elsõ 10 sorát ne küldje tovább, csak a maradékot. (Tehát a TAKE-hez hasonlóan ez is szuri az inputot)

4)

 PIPE < A A A ] SPEC 1-8 13 ] CONSOLE
A spec igen hasznos stage parancs, amivel egy megfeleltetést lehet megadni az input és az output rekord között. A SPEC alakja általában:
 SPEC input output
Pontosabban több ilyen input-output pár követhet egy SPEC-t. Ebben a példában az 1-18 az input 1. és 18. pozíciója közti reszt specifikálja, az output a 13. pozíciót. Vagyis az input rekord elsõ 8 karaktere az outputban a 13. pozíción fog kezdõdni. A SPEC-nek nem csak karakter pozíció adható meg, hanem pl. szó száma is. Pl. a fenti példában a SPEC-t írjuk át így:
 SPEC W2 1 W6 NW
Ez azt mondja, hogy az input második szava az outputban az elsõ pozícióra, a hatodik szó pedig a kimenet maradék részére kerül.

5) Legyen az A A A file olyan, hogy az egyes soraiban az elsõ szó egy felhasználó neve, amit egy szöveg követ. El akarjuk küldeni az összes felsorolt felhasználó számára a neve után álló szöveget. Pl. ha a file a következõ:

USER1 Hello :))
USER2 Veled nem akarok beszelni.
akkor az alábbi csõ szépen szétküldi az üzeneteket:
 PIPE < A A A ] SPEC /MSG/ 1 1-* NW ] CP
A SPEC után a /MSG/ egy CP parancs, de a spec csak annyit csinál, hogy a / jelek közti szöveget berakja az output 1. pozíciójára. Az 1-* az egész input rekordot jelöli, és a SPEC ezt az MSG után fūzi. Az így kapott sorokat pedig egyenként továbbküldi a következõ stage parancsnak, ami a CP. A CP - ki hinne - egy CP parancsot tud végrehajtani. Pl. a file második sorából a SPEC a CP-nek egy MSG NEM De] sort küld tovább, amit a CP parancskent értelmez, és végrehajt. Megjegyzés: A csõben általában nem nyelõdik el az adat: pl. a CP-bol meg tovább lehetne irányítani a CONSOLE-hoz, onnan egy file-ba, es meg tovább is lehetne küldeni. A file-ba irányítas ugyanúgy megy, mint UNIX vagy DOS alatt: > jellel.

Pl. egy file másolása megoldható így is:

 PIPE < A A A ] > B B A
Fontos formai megjegyzés: Még mielõtt továbbmennénk a pipe-oknak az elemzésében, egy formai szempontból fontos megjegyzést kell tenni. A PIPE-okat is lehet szépen és csúnyán leírni, valahogy úgy, mint ahogy a C nyelvben is. Ha tördelés nélkül írjuk a pipe-ot, akkor a bonyolultabb (multistream-es pipe a pipe-okban, stb...) csöveket már végképpen nem fogjuk megérteni. Nagyon fontos a megfelelõ tagolás, ami hasonlóan is történhet, mint például a programozási nyelveknél az egyes ciklusok leírása (ugyanis ciklusmagnak tk. a belsõ pipe-ok vehetõk). Fontos továbbá az is, hogy láthatóan elkülönítsük a párhuzamos csöveket egymástól. A továbbiakban megtalálható leírási módot bátran merem ajánlani minden leendo pipe mágusnak, de más jól áttekinthetõ módon is lehetséges a leírás. A REXX miatt a PIPE-ot (mivel parancsmodul hívásról van szó), aposztrófok közé kell rakni, ami azt teszi lehetõvé, hogy tetszõleges számú sorban is le lehessen írni. &IACUTE;gy tulajdonképpen nem jelentkezik korlát arra vonatkozóan, hogy milyen hosszú és maximum hány stage parancsból álló pipe-okat írhatunk. A válasz az, hogy tetszõlegeset. Tehát a továbbiakban minden stage parancsot külön sorba írunk, és minden sort aposztrófok közé rakunk, ahol a végére akkor kell vesszot tenni, hogy ha azt szeretnénk, hogy a REXX interpreter egy sornak értelmezze.

6) Most nézzünk egy olyan példát ahol PIPE egy másik PIPE-ot generál le, majd futtatja is. Legyenek adottak a NEVEK TXT A file, mely userid-ek listáját tartalmazza, minden sorban egyet, illetve a LEVEL TXT A file, amely egy levelet tartalmaz, amit minden user-nek szét szeretnénk küldeni úgy, hogy minden file elején ott legyen a 'Tisztelt ' szöveg. A feladatmegoldásból most hagyjuk el az elküldést, mivel ez elég speciális a CMS alatt, inkább generáljuk le file-okba a leveleket ' LEVEL A' névvel. Ezt a következõ csõvezetékkel is meg lehet oldani:

'PIPE ',
    ' < NEVEK TXT A',
    '] SPEC $PIPE (STAGESEP %)',
                ' < LEVEL TXT A',
                '% STRLITERAL /Tisztelt $ 1 f1 n $/',
                '% > $ n f1 n $ LEVEL A$',
    '] CMS'
 
Mint látható, kicsit furmányos módon van itt megoldva a belsõ csõvezeték elkészítése, illetve lefuttatása. Most szándékosan kerültem a callpipe kulcsszó használatát, ugyanis így látható igazán, milyen remekül lehet kombinálni a REXX, a PIPE és az operációs rendszer adta lehetõségeket. A második stage parancs (SPEC) bemenete a userid-ekbol álló rekordok, ahol minden userid rekordból elkészítünk egy olyan szöveges rekordot, ami egy PIPE leírását tartalmazza. Majd a legvégén ezt adjuk át a CMS interpreternek végrehajtásra. Tehát ha például a NEVEK TXT A file csak az OPERATOR userid-et tartalmazza, akkor a SPEC által legyártott pipe a következõképpen fog kinézni (a vesszõnél összeillesztve a két sort):
'PIPE (STAGESEP %) < LEVEL TXT A % STRLITERAL /Tisztelt OPERATOR %',
 ' > OPERATOR LEVEL A'
 

Példák multistream-ekre:

7)
 'PIPE (END ?)',
      ' < A A A',
      '] C: FIND A',
      '] > VA A A',
     '?',
      ' C:',
      '] > NA A A'
Ez egy példa több pipeline összekapcsolására. Az (END ?) opció mondja meg, hogy a pipeline-okat ? választja el a felsorolásban. Az elsõ pipeline az A A A file-ból olvas, és tovább küldi az adatokat a FIND stage parancsnak. A FIND az elsõ pozíción keres A betut a rekordban. A keresés case sensitive, és figyelni kell, hogy az A és a ] közé ne kerüljön szóköz, mert akkor "A "-t fog keresni. A find elõtti C: egy cimke definíció, amit a következõ pipeline elején rögtön fel is használunk. A FIND két kimenetet is general: az elsõdleges kimenetre kerülnek azok a sorok, amikben sikeres volt a keresés. A többi sor egy másodlagos kimenetre kerül. Az elsõdleges kimenet tartalma megy tovább abban a csõvezetékben, amelyikben a FIND stage szerepel; a következõ > VA A A stage parancs egy file-ba írja ezeket a sorokat. A másodlagos kimenet a másik pipeline elején lep be. Az ugyanis egy C: hivatkozással kezdõdik, ahol a C ugyanaz a címke, mint amit a FIND-nál definiáltunk. Ezért a második pipeline bemenete a FIND másodlagos kimenete lesz, és ez íródik ki vegül a NA A A file-ba. Ezzel végsõ soron az A A A file-t az elsõ oszlopban szereplõ betü alapján két file-ba osztottuk szét: a VA A A tartalmazza az A-val kezdõdõket, a NA A A a többit.

Megjegyzés: Egy címkére csak akkor lehet hivatkozni, ha megelõzõleg már valahol definiáltuk. Ekkor viszont akárhány referencia lehet rá.

8)

   'PIPE (END ?)',
         ' < 1 F A',
         '] F: FANIN',
         '] > 3 F A',
        '?',
         ' < 2 F A',
         '] F:'
Ez egy olyan csõ, ami nem szétágazik, hanem összekapcsol két pipelinet. Az elsõben van egy FANIN nevū stage parancs. Ez azt tudja, hogy tetszõleges számú inputját egymás után fūzi. Ehhez a stage-hez az F címke tartozik. A PIPE másik csõvezetéke egyszerūen beolvassa a 2 F A file-t, és továbbadja az F címkével megjelölt pontra, vagyis a FANIN bemenetére. A FANIN kimenete a 3 F A-ba megy. Ezzel az 1 F A és a 2 F A a 3 F A-ba egymás után fuzve kerül.

Megjegyzés: A FANIN párja a FANOUT, ami több kimenetre tud ágazni.

9)

 'PIPE (END ?)',
       ' < 1 F A',
       '] F: SPEC 1-* 1 WRITE SELECT 1 1-* 1',
       '] > 3 F A',
      '?',
       ' < 2 F A',
       '] F:'
Most FANIN helyett a SPEC-et használjuk, meghozza arra, hogy a két file sorait felváltva fésüljük össze a harmadikba. Az elsõ 1-* 1 mondja meg, hogy az elsõdleges inputról a beolvasott rekordot az output rekord elsõ pozíciójára tegyük. A WRITE ezt ki is írja rögtön az outputra, majd a SELECT 1 átvált a másodlagos inputra, és onnan is a következõ rekord a kimenetre másolódik. Az elsõdleges input száma 0, a másodlagosé 1, s.í.t. A stage parancs alapban az elsõdleges inputról olvas, az átváltáshoz kell a SELECT.

10)

  'PIPE ',
      ' < FILE1 FIL A',
      '] A: COLLATE',
      '] > EGYEZO REC A',
     '?',
      ' < FILE2 FIL A',
      '] B:',
      '] DIF1 REC A',
     '?',
      ' B:',
      '] > DIF2 REC A'
Ez a PIPE a "FILE1 FIL A" es a "FILE2 FIL A" nevū file-okat fogja összehasonlítani. Az elõfeltétel, hogy mindkét file rendezett legyen ugyanolyan sorrendbe és szempont szerint. Ekkor az "EGYEZO REC A" nevū file-ban megtalálhatjuk az összes olyan rekordot, amelyek a két bemeneti file-ban azonosak, a "DIF1 REC A" nevū file fogja tartalmazni azon rekordokat, melyek a "FILE1" file-ból valók, de nem szerepelnek a "FILE2" file-ban, illetve a "DIF2 REC A" tartalmazza az összes olyan rekordot, amit a "FILE2" file tartalmaz, de a "FILE1" nem. A COLLATE stage parancs mūködését szemlélteti a következõ ábra:
 
                  *----------*      *----------------* Primary
                  !          !----->!azonos MASTER és! Output
*-----------*     !    C     !      !DETAILS rekordok! Stream
!  MASTER   !---->!          !      *----------------*
!           !     !    O     !
*-----------*     !          !
Primary Input     !    L     !
   Stream         !          !      *----------------* Secondary
                  !    L     !----->!MASTER rekordok ! Output
                  !          !      !DETAILS nélkül  ! Stream
                  !    A     !      *----------------*
                  !          !
*-----------*     !    T     !
!  DETAILS  !---->!          !
!           !     !    E     !      *----------------* Tertiary
*-----------*     !          !----->!DETAILS rekordok! Output
Secondary Input   !          !      !MASTER nélkül   ! Stream
   Stream         *----------*      *----------------*
 
 
Természetesen a COLLATE stage parancs elõfeltétele az eddigiek alapján már nagyon könnyen biztosítható: csupán egy SORT stage parancsot kell mind az elsõdleges, mind a másodlagos pipeline-okban elhelyezni, így a rendezettség és a pufferelés is biztosítva lesz.

Részletesebb leírás a stage parancsok szintaktikájához.

A PIPE CMS parancs az adatfeldolgozás egyik hatékony eszköze.
  PIPE (opciók) stage1 ! stage2 [![...] stageN]
A PIPE parancs operandusai a STAGE parancsok, amelyek az adatot transzformálják. Egy stage a stage parancsból és annak operandusaiból áll, a stage-eket stage szeparátorok (X'4F') választják el egymástól. A stage adatokat egy eszközrõl (diszk,szalag) vagy az elõzõ stage outputjáról olvas. Minden stage outputja a következõ stage inputja is egyben. Az adatok rekordokból állnak és a rekordok folyamát STREAM-nek nevezzük. A bemenõ és kimenõ stream-ekbõl több is lehet (elõdleges input stream, másodlagos input stream) pl.: a locate stage parancs - amely megkeresi azokat a rekordokat amelyekben egy adott string szerepel - a megtalált rekordokat az elsõdleges output stream-jére a maradékot pedig a másodlagos output stream-jére írja. Azokat a pipeline-okat, amelyekben több input és output stream-et használunk, multistream pipeline-nak nevezzük.
 
 elsõdleges                                            __________
 input      ___________           ___________         !          !
-----------!           ! output  !           !--------! stage 3  !------
 stream    !  stage 1  !---------!  stage 2  !____    !__________!
-----------!___________! stream  !___________!    !
másodlasoa                                        !
 input stream                                     !    __________
                                                  !   !          !
                                                  !___! stage 4  !------
                                                      !__________!
 
 
Sok beépített stage parancs van, ezekrõl részletes help-et a

HELP PIPE MENU paranccsal kérhetünk.

A stage parancsokat különbözõ csoportokba oszthatjuk:

A beépítetteken kívül mi is írhatunk újabb stage parancsokat REXX-ben vagy Assemblerben.

Röviden a PIPE mûködésérõl:

Amikor kiadjuk a PIPE paracsot, elõször a scanner ellenõrzi a szintaxist és azt, hogy az egyes stage parancsok léteznek-e. Ha hibát észlel, nem nulla rc-vel befejezõdik a pipe végrehajtása. Abban az esetben, ha a szintaxis korrekt, és léteznek a stage parancsok, akkor elkezdõdhet a végrehajtás, amit a dispatcher irányít. A dispatcher dönti el, hogy mikor melyik stage kapjon vezérlést. Ez azt jelenti, hogy nem elõre meghatározott a végrehajtási sorrend. A dispatcher bármikor felfüggesztheti egy stage végrehajtását és egy másik stage-nek átadhatja a vezérlést. A pipe akkor áll le, amikor az összes stage befejezõdik. Ekkor az eddig elõforduló legrosszabb rc-t adja vissza. (A legrosszabb rc negatív szám esetén a legkisebbet jelenti,ha pedig negatív szám nem szerepel köztük, akkor a legnagyobb pozitív számot.)

2.Device Driver-ek.

A pipe és a külvilág között adatokat device driver-ek segítségével mozgatunk.
  LITERAL sztring
Ez a stage parancs a sztringet beírja az elsõdleges output stream-jére és utána az elsõdleges input stream-jén lévõ rekordokat is átmásolja oda.
  CONSole [EOF /string/]
A CONSOLE stage paranccsal sorokat lehet olvasni és írni a terminálra. Ha a CONSOLE az elsõ stage a pipeline-ban, akkor beolvassa a rekordokat a terminálról, és kiírja azokat az elsõdleges output stream-jére. Amikor a CONSOLE nem az elso stage, akkor az elsõdleges input stream- jén lévõ rekordokat kiírja a terminálra. A konzolról való olvasás alapértelmezés szerint üres sor beolvasása után áll le, ezt az EOF opcióval változtathatjuk meg.

Példa: A PROFILE EXEC elsõ 10 sorának kiírása a képernyõre.

  pipe < PROFILE EXEC ! take 10 ! console
  < fn ft [fm]
A < stage parancs CMS file-ok tartalmának beolvasására szolgál. A beolvasott rekordokat kiírja az elsõdleges output stream-jére. Ha a filemódot nem adjuk meg, elõször a virtuális tárban keres, utána az accessált minidiszkek és könyvtárak között. Amikor fm-nek *-ot adunk meg, akkor nem keres a virtuális tárban. Ha a file nem létezik, akkor hibaüzenetet ad. Amennyiben a nem létezõ a file-okat üresként akarjuk kezelni, használjuk a FILEFAST stage parancsot.
 > fn ft fm [formátum]
Kiírja a megadott file-ba az elsõdleges input stream-jén érkezõ rekordokat. A formátum lehet fix vagy változó. A változó formátum az alapértelmezés. Ha a file nem létezik, létrehozza, ha létezik felülírja a tartalmát.

Példa: Egy egysoros file létrehozása.

 pipe literal this is a single line ! > ONE LINER A
 >> fn ft [fm [formatum]]
A >> stage paranccsal lehet CMS file-hoz rekordokat hozzáfûzni. Nem szerepelhet az elsõ stage-ként a pipe-ban. Az elsõdleges input stream-jén lévõ rekordokat a megadott file-ba írja. Ha a file létezik, hozzáfûzi a végéhez, ha nem létezik létrehozza azt. A formátum: ld. >. Az fm alapértelmezése A.

Példa: A következõ pipe hozzáad a dolgozók és az alkalmazottak file-hoz egy személyt.

 pipe literal JAMES ! >> DOLGOZOK FILE A ! >> ALKALMAZ OTTAK A
 FILEfast fn ft [fm [formatum]]
A FILEFAST stage parancs beolvas vagy kiír egy CMS file-t. < -tól annyiban különbözik, hogy nem ír hibaüzenetet, ha a file nem létezik és a virtuális tárban nem keresi a file-t. Ha a filefast nem az elsõ stage, akkor megegyezik a >> stage paranccsal.

Példa: Az INPUT FILE A -ban lévõ szavakat megszámolja és kiírja a terminálra.

   pipe filefast INPUT FILE A ! count words ! console
 FILESLOW fn ft [fm [FROM recno] [formatum]]
Ez a stage parancs rekordokat olvas vagy hozzáfûz az adott CMS file- hoz. Abban különbözik a FILEFAST-tól, hogy megadható hányadik rekordtól végezze a mûveletet.

Példa: Az INPUT FILE A 20. rekordjától kezdve írja ki a file tartalmát a terminálra.

   pipe fileslow INPUT FILE A from 20 ! console
Az OUTPUT FILE A 10. rekordjaként hozzáfûzi a CP QUERY TIME eredményét. A file 10. rekordját felülírja, ha a file változó formátumú:
   pipe cp query time ! fileslow OUTPUT FILE A from 10
Amennyiben a file fix formátumú, akkor a rekordnak meg kell egyeznie a file rekordhosszával:
   pipe cp query time ! pad 80 ! fileslow OUTPUT FILE A from 10
 FILEBACK fn ft [fm]
A FILEBACK stage parancs segítségével lehet egy CMS file tartalmát visszafelé olvasni. A FILEBACK csak az elsõ stage lehet a pipeline-ban.
 FILERAND fn ft [fm [BLOCKED [RECNO [rrange]]]]
A FILERAND stage parancs megadott rekordokat olvas be egy CMS fileból. BLOCKed kulcsszóval lehet megadni, hogy a beolvasott rekordokat egy rekordként írja ki az output stream-re. Ekkor a file-nak fix blokkosnak kell lennie.

RECNO az elsõ 10 oszlopban a rekord sorszámát írja a rekord elé. rrange-nek a rekordok sorszámát kell megadni, ha nem adjuk meg és a FILERAND az elsõ stage parancs, akkor nem olvas be a file-ból.

Példa: Az INPUT FILE A 3, 10 ,15, 16, és 20-30 rekordját beolvasni és kiírni a terminálra:

   pipe filerand INPUT FILE A 3 10 15.2 20-30 ! console
A rekordok sorszámát nem kell növekvõ sorrendben megadni:
   pipe filerand INPUT FILE A 3 10 1 2 12 5 4 ! console
Az INPUT FILE 20-30. rekordját a képernyõre írja:
   pipe literal 20-30 ! filerand INPUT FILE A ! console
FILEUPDAte fn ft [fm [formatum]]
Ezzel a stage paranccsal CMS file-okban lévõ rekordokat lehet megváltoztatni. Nem lehet az elsõ stage a pipeline-ban. Az elsõdleges input stream összes rekordjának 1-10 oszlopokban tartalmaznia kell annak a rekordoknak a számát amit felül akarunk írni.

Példa:

    /* UPDT EXEC */
 
    'pipe',
 
     '< INPUT FILE',            /* beolvassa az INPUT FILE-t */
 
     '! specs recno 1 1-* next',/* rekord számokat tesz a rekordok elé */
 
     '! locate 11.4 /Five/',    /* kiválasztja a "Five"-ot tartalmazó */
 
                                /* rekordokat */
 
     '! specs 1-* 1 /Four/ 11', /* megváltoztatja "Five"-t "Four"-ra */
 
     '! fileupdate INPUT FILE', /* a változtatott rekordokat felülírja */
 
     '! console'                /* kiírja a képernyõre */

Rexx változókat író és olvasó stage parancsok. (STEM,VAR)

 STEM stem
A STEM stage paranccsal REXX vagy EXEC 2 összetett változókat lehet kezelni. Ha az elsõ stage a pipeline-ban, akkor a változók értéke bekerül a csõbe, ellenkezõ esetben a csõben lévõ rekordok kerülnek bele a változóba. Az összetett változó 0.elemével a csõbe belekerülõ rekordok számát kell megadni.

Példák:

 colors.0=3; colors.1=red;colors.2=white;colors.3=black;
 pipe stem colors. ! console
 pipe literal blue ! literal yellow ! literal red ! stem colors.
A stem 0. elemébe beleírja a darabszámot.
 VAR változó
Abban az esetben, ha ez az elsõ stage, akkor beolvassa a változót a csõbe, ellenkezõ esetben kiírja a megadott változóba a pipeline elsõ rekordját.

Xedit-ben mûködõ device driver-ek. (XMSG,XEDIT)

 XMSG
Az XMSG stage parancsot egy CMS file editálása alatt használhatjuk. A csõben lévõ összes rekordra kiadja az XEDIT MSG parancsot. A rekord elsõ 251 byte-ot használja a szöveg kiírására. Ezután az elsõdleges input stream-jén lévõ rekordokat átmásolja az elsõdleges output stream-jére.

Példa: A CP QUERY TIME parancs megjelenítése editálás közben:

   pipe cp query time ! xmsg
Szöveg kiírása az msg sorba:
 pipe literal Hello XEDIT user. ! xmsg
 XEDIT [fn [ft [fm]]]
Az XEDIT stage parancsot CMS file-ok editálása közben használhatjuk. Amennyiben ez az elsõ stage parancs, akkor az aktuális sortól kezdve beolvassa a fileból a rekordokat és kiírja az elsõdleges output stream-jére. Ha nem az elsõ stage parancs, akkor az elsõdleges input stream tartalmát beleírja az fn ft fm operandusként megadott editált file-ba, és a rekordokat lemásolja az elsõdleges output stream-jére is.

Példa: A PROFILE EXEC editálása közben, egy PFKEY SETTINGS A file-t hozunk létre:

   pipe xedit ! locate /SET PF/ ! > PFKEY SETTINGS A
Ha a file fix formátumú, akkor a csõben lévõ rekordok hosszának meg kell egyeznie a file rekordhosszával. Ebben a példában a PAD stage parancs kiegészíti az a betût és utána írja be az éppen editált file-ba.
  pipe literal a ! pad 80 ! xedit

További device driver-ek: (APPEND,PREFACE)

 APPEND stage_parancs [operandus]
Lemásolja az input stream-jén lévõ rekordokat az output stream-re, ezután az operandusban megadott stage parancsot futtatja és az eredményt az output stream-re írja.

Példa: Kiírja a képernyõre a q disk és a listfile * assemble * eredményét: pipe cms query disk ! append cms listfile * assemble * ! console Két file tartalmát egy harmadikba másolja:

  pipe < input1 file a ! append < input2 file a ! > output file a
PREFACE stage_parancs [operandus]
Elõször végrehajtja az operandusában megadott parancsot, és utána másolja át az input stream-jén lévõ rekordokat az output stream-re.

Példa: Ebben az esetben elõször a listfile eredménye az elsõ:

  pipe cms query disk ! preface cms listfile * assemble * ! console

3.Filterek.(Szûrõk.)

Rekordok kiválasztása. (LOCATE,NLOCATE,FIND,NFIND,TOLABEL,FRLABEL,UNIQUE)
 Locate szeparátor inputrange /sztring/
A locate stage parancs azokat a rekordokat írja ki az elsõdleges output stream-jére amelyek tartalmazzák a sztring-ként megadott karaktersorozatot, másodlagos output stream-jére pedig a maradék rekordot. Alapértelmezés szerint az egész rekordot figyelembe veszi, de meg lehet adni pozíciótókat vagy hogy hányadik szótól keressen.

Szeparátornak megadható WS (WORDSEParator) vagy FS (FIELDSEParator). WS alapértelmezés a szóköz, FS alapértelmezés a TAB (X'05'). Például - jellel elválasztott szavak közül a harmadikban keressük a c betût:

  pipe literal a-b-c ! literal d-e-f ! locate ws - w3 /c/ ! console
Ebben az esetben a megadott szóelválasztó jelek a - és +, - esetén a 3. szavakban keresünk + esetén pedig a 2.-ban:
  pipe literal a-b-c ! literal d+c+f ! locate (ws - w3 ws + w2)  /c/ !,
 
  console
Itt a 2. mezõben akarunk keresni, ahol a mezõk - jellel vannak elválasztva:
  pipe literal a b-c d ! literal c f-g h ! locate fs - f2 /c/ ! console
Oszloppozíciók is megadhatók az inputrange-nél:
  pipe literal abc ! literal def ! locate 2-* /b/ ! console
/ jel helyett más karaktet is használhatunk a lényeg, hogy megegyezzen az elsõ és utolsó karakter:
 pipe literal z=x/y ! locate ,x/y, ! console
A locate stage parancsot arra is használhatjuk, hogy a csõben lévõ rekordokat hossz szerint válogassuk ki. Ebben a példában azok a rekordok mennek tovább a csõben, amelyek 2 vagy annál hosszabbak:
  pipe literal a ! locate 2 ! console
 NLOCATE szeparátor inputrange /sztring/
Kiválasztja azokat a rekordokat amelyek nem tartalmazzák a megadott sztringet és ezeket írja az elsõdleges output stream-jére.
 FIND szöveg
Kiválasztja azokat a rekordokat, amelyek a megadott karakterekkel kezdõdnek. Minden karakternek egyeznie kell, kivéve a szóközt és az aláhúzást (_). Szóközre minden karakter illeszkedik, aláhúzásra pedig csak a szóköz.

Ebben a példában mindkét literalt kiírja a terminálra, mert a find után a the és most között szóköz van:

  pipe literal thermostat ! literal the most interesting ! find the most
 
  ! console
Itt csak a második stage-beli el so-t találja meg, mert az aláhúzás a szóközt helyettesíti:
  pipe literal el+so ! literal el so! find el_so! console
 TOLABel sztring
Addíg másolja az elsõdleges output stream-re a rekordokat, amíg megtalálja a megadott sztringet, a maradékot pedig a másodlagos output stream-re másolja. Az egyezéshez a sztringnek az elsõ oszlopon kell kezdõdnie.
 FRLABel sztring
Megvizsgálja az elsõdleges input stream-jén lévõ rekordokat és, amennyiben talál a sztringel egyezõt, akkor onnan kezdve az összes rekordot kiírja az elsõdleges output stream-jére, a maradékot pedig a másodlagos output stream-jére.
 UNIQue [oszlopok] [LAST!FIRST!SINGLEs!MULTiple!PAIRwise]
Alapértelmezés szerint az elsõdleges input stream-rõl olvassa a rekordokat és a teljes rekordot összehasonlítja az utána következõvel, ha egyezik, akkor addíg olvas amíg nem egyezõt talál és csak az utolsót tartja meg az egyezõk közül.

Megadható, hogy ne a teljes rekord egyezését vizsgálja, hanem csak meghatározott oszlopokat. Ebben a példában az elsõ két oszlopot vizsgálja és kiírja az elso-t, mert az az utolsó:

 pipe literal elso ! literal elso1 ! uniq 1-2 ! console
Az opciók közül a LAST az alapértelmezés, így az egyezõk közül az utolsó rekordot hagyja meg, ezt megváltoztatni a FIRST opcióval lehet, ekkor az elsõ egyezõ rekordot fogja kiírni. Ha megadjuk a SINGLEs opciót, akkor az összes egyezõ rekordot törli, MULTiple esetén pedig a különbözõket. A PAIRwise opció megadása esetén az egyezõ párokat a másodlagos output stream-re írja.

Rekordok kiválasztása pozíció alapján. (TAKE,DROP)

 TAKE [FIRST!LAST] n
Kiválasztja az elsõ vagy utolsó n rekordot. Az alapértelezés FIRST 1.

Példák: n helyére *-ot is megadhatunk, ekkor az összes rekordot kiírja:

 pipe < string list ! take * ! console
Az utolsó három rekord kiírása:
 pipe cms query accessed ! take last 3 ! console
 DROP [FIRST!LAST] n
Elhagyja az elsõ vagy utolsó n rekordot. Az alapértelmezés FIRST 1.

Példa:

  pipe cms q limits ! drop ! console

Rekordok változtatása. (SPLIT,JOIN,PAD,CHOP,STRIP,CHANGE,SPECS)

 SPLIT [MINimum n!oszlop [BEFORE!AFTER]!karakter!any /string/]]
A szövegben megadott pozíciókon elválasztja a rekordokat. Megadható egy karaktertõl vagy egy egész sztringtõl való relatív távolság, és az, hogy ezen belül az adott oszlop elõtt vagy után vágjon.

Példák: Az alapértelmezés a szóközöknél való vágás:

  pipe literal elso masodik ! split ! console
Az 1 vagy 3 karakterektõl jobbra lévõ 2.oszlop után vág:
  pipe literal 12134df117a1b0 ! split 2 after anyof /13/ ! console
Az 1 vagy 3 karakterektõl balra lévõ 2.oszlop után vág:
  pipe literal 12134df117a1b0 ! split -2 after anyof /13/ ! console
Az 1 vagy 3 karakterektõl jobbra lévõ 2.oszlop elõtt vág:
  pipe literal 12134df117a1b0 ! split 2 before anyof /13/ ! console
Az 1 vagy 3 karakterektõl balra lévõ 2.oszlop elõtt vág:
  pipe literal 12134df117a1b0 ! split -2 before anyof /13/ ! console
A betûknél vág és lehagyja azokat:
  pipe literal 123a4d56 ! split not f0.10 ! console
A megadott sztringnél vág:
  pipe literal 1213a4d56 ! split string /13/ ! console
  JOIN [N!*!/sztring/]
Konkatenálja a rekordokat az operandusban megadott csoportok szerint. N-el lehet megadni, hogy az elsõ rekordhoz még hány rekordot fûzzön, * esetén pedig az összes rekordot konkatenálja. Ha megadunk egy sztringet, akkor az összefûzött rekordok közé azt is bemásolja. Alapértelmezés szerint párosával konkatenálja a sztringeket.

Példák:

  pipe literal 1 ! literal 2 ! literal 3 ! join ! console
 
  pipe literal 1 ! literal 2 ! literal 3 ! join * ! console
 
  pipe literal 15! literal 24! literal 45! join 2 /a/ ! console
  PAD [left!right] [n] [karakter]
Ezzel a stage paranccsal lehet rekordokat kiegészíteni. A rekordokat jobbról vagy balról egészíthetjük ki egy vagy több karakterrel az alapértelmezés jobbról szóközökkel.

Példa: Jobbról az 50. oszlopig .-al kiegészít:

  pipe cms q accessed ! pad 50 . ! console
  CHOP [oszlop] [before!after] [karaktersorozat!anyof!string /sztring/]
Rekordok végét levágja, alapértelmezés szerint a 80. oszlopnál.

Példa: A 65. oszloptól vág:

  pipe cms listfile * * a (date ! chop 65 ! console
Az 1 (hexa f1) elõtt vág minden rekordban:
  pipe cms q accessed ! chop f1 ! console
  STRIP [LEADING!TRAILING [NOT!TO]] [ANYOF!STRING /sztring/]
A strip stage paranccsal a kezdõ és végkaraktereket lehet levágni. Alapértelmezés szerint a rekordok elõtti és mögötti szóközöket vágja le.

Példák:

  pipe literal    Hello      ! strip ! console
 
  pipe literal 0000120 ! strip leading string /0/ ! console
 
  pipe literal   0011 4 ! strip anyof /10 / ! console
  CHANGE [ANYcase] [oszlopok] /string1/string2/ [n]
A string1 karaktesorozatot a string2-re cseréli. Az ANYcase paramétererrel adhatjuk meg, hogy a kis és nagybetû közötti különbséget ne vegye figyelembe. Az oszlopok paraméterétõl függ, hogy hol keresi az egyezést, alapértelmezés szerint az egész rekordban. Az n paraméter azt adja meg, hogy a string1 maximum hány elõfordulását változtassuk string2-re.

Példák: A b-t lecseréli def-re:

  pipe literal a b c ! change any /B/def/ ! console
Az elsõ 4 oszlopban lévõ 1234-et lecseréli 5678-ra:
  pipe literal 12341234 ! change (1-4) /1234/5678/ ! console
Ez csak az elsõ két b-t fogja kicserélni d-re:
  pipe literal a b b b a c ! change 1-7 /b/d/ 2 ! console
  SPECS input [konverzió] output [igazítás]
Ezzel a stage paranccsal output rekordokat állíthatunk elõ, már meglévõ input rekordokból vagy megadott sztringbõl. Egy input rekordból több output rekordot vagy több input rekordból egy output rekordot is elõállíthatunk. Az input egy literál vagy a bejövõ rekord egy része pl.:1-5. oszlopa. A literált elválasztó jelek között adhatjuk meg, pl.: spec /abc/ 3, ,xyz, 8 vagyis nem kell ugyanazt az elválasztó jelet használni egy spec-en belül. A bejövõ rekordot szavak, mezõk vagy oszlopok alapján darabolhatjuk, ezen kívül megadható, hogy mit tekintsen szó és mezõ szeparáló jelnek.

Példák: Az alapértelmezés szerinti szó elválasztó jel a szóköz, a mezõ elválasztó jel pedig a tabulátor:

  pipe literal abc def ghi jkl ! specs word 2-4 1 ! console
A word 2-4-et lehet w2-4-re rövidíteni, a szavakat elválasztó jel megadása WordSep kulcsszóval történik:
  pipe literal ?abc?def?ghi?jkl ! specs ws ? w2-4 1 ! console
 
  pipe literal ab cd-ef gh ! specs fs - field 1 1 field 2 10 ! console
 
  pipe literal ?ab?cd?ef ! specs fs ? f1 1 f2 2 f3 5 f4 9 f5 14 ! console
A rekord végére negatív számmal hivatkozhatunk:
  pipe literal ABCDEFGHIJKLMN! spec -8;-1 1 ! console
A rekordokat megszámozhatjuk a recno kulcsszóval:
  pipe literal ABC ! literal XYZ ! specs recno 1 1-* 12 ! console
Ha több input rekordól akarunk egy output rekordot elõállítani, akkor a specs read operandusát lehet használni:
  pipe literal ABCD! literal 123 ! specs 1-* 1 read 1-3 4 ! console
Az input adaton konverziót lehet végezni, ezek lehetnek például: c2b, c2d, d2c, c2x.

Az output mezõnél mondjuk meg, hogy az elõbbi adatot az output rekord melyik részére akarjuk tenni, és végül, hogy hová igazítsa az adatot. Pl.: specs 1-* x2c 5 right

Az output mezõben nemcsak oszlop pozíciót adhatunk meg, hanem a Next és NextWord kulcsszóval azt, hogy a következõ pozícióra vagy egy szóköz kihagyásával a következõ pozícióra tegye az elõállított adatot:

  pipe literal alma ! specs 1-* 1 /korte/ nw ! console
Több output rekordot a write operandussal lehet elõállítani egy input rekordból:
  pipe literal ABC123! specs 1-3 1 write 4-6 4 ! console

Még néhány filter: (DUPLICATE,COUNT,SORT,BUFFER)

  DUPlicate [n!*!-1!1]
Az input rekordokból adott számú másolatot készít.

Példa:

  pipe literal abc ! duplicate 1 ! console
  COUNT BYTES!CHARS!CHARACTErs!WORDS!MINline!MAXline
Az input streamben lévõ byte-okat, szavakat vagy rekordokat számolja meg, ezen kívül visszaadhatja a legrövidebb vagy leghosszabb rekord hosszát.

Példák:

  pipe < input file a ! count bytes ! console
 
  pipe < input file a ! count words ! console
 
  pipe < input file a ! count lines ! console
  SORT [COUNT!UNIQue] [Ascending!Descending]
Az input rekordokat rendezi növekvõ vagy csökkenõ sorrendben. A count opció esetén a rekord elé teszi 10 karakteren azt, hogy hány ezzel megegyezõ számú rekordot talált. A másolatokat kitörli ugyanúgy mint amikor a unique opciót adnjuk meg.

Példák: A rekordokat csökkenõ sorrendben rendezi:

  pipe cms listfile * assemble * ! sort desc ! take 10 ! console
Az rekord elsõ 8 karaktere alapján rendez:
  pipe cms listfile * assemble * ! sort 1.8 ! take 10 ! console
Kitörli a duplikátumokat:
  pipe < input file ! split ! sort unique ! console
  BUFFER [n!/string/]
Ezen a stage-en összegyûjti az összes rekordot és n-szer kíírja az output stream-re, a megadott string-el elválasztva.

Példa: Kétszer kiírja a 2 és 1-et úgy, hogy egy 3-at is közé ír:

  pipe literal 1 ! literal 2 ! buffer 2 /3/ ! console

4.Host parancsok.

Ezek olyan stage parancsok, amelyek segítségével CMS és CP parancsokat lehet kiadni, és az eredmény a csõbe iródik.
  CMS [string]
Példák:
  pipe cms query disk ! > space data a
 
  pipe literal q accessed ! literal listfile * * a ! cms ! console
  COMMAND [string]
mint az ADDRESS COMMAND rexx-ben nem keresi az exec-eket és a CP parancsokat.
  pipe command QUERY DISK ! > space data a
  CP [maxhossz] [string]
Példa:
  pipe cp query users ! > users data a
 
  pipe literal ipl ! cp

5.Stage parancsok irása.

Stage parancsokat Rexx nyelven írnhatunk. A programot tartalmazó file típusa rexx. A saját stage parancsunk pipeline alparancsok segítségével kommunikál a csõvel.

Pipeline alparancsok:

Multistream Pipelines.

Azokat a pipeline-okat nevezzük multistream pipeline-oknak, amelyekben több input vagy output stream-et használunk.

Egy pipe parancsban több pipeline is lehet, úgy, hogy ezek nem kapcsolódnak egymáshoz. pl.:

   'pipe (endchar ?) < profile exec a ! > profile save a ?',
    '< all notebook a ! > all save a'
A ? jelzi a pipeline végét. Ebben a pipeline-ban a rekordok teljesen függetlenek egymástól. Azok a stage-ek, amelyek egymás után következnek, automatikusan össze vannak kötve. A stage-ek másodlagos, harmadlagos, .... stream-jeit címkék segítségével használhatjuk. A címke 1-8 hosszú karakter lehet amit egy : követ.(pl.: a: ) A címkét az elé a stage elé kell írni, amely másodlagos output-ját szeretnénk használni, ez a címke definíció. Ezután a címkére már hivatkozhatunk a pipe késõbbi részén. Minden címke hivatkozás a stage parancs egy újabb input vagy output stream-jét definiálja. A címke hivatkozás pozíciója határozza meg, hogy az input-ot vagy az output-ot kapcsoljuk össze.

A címkére háromféle pozíción hivatkozhatunk:

1. a pipeline elején, ekkor a másodlagos output-ot kötjük össze pipe (end ?) stage A! a: stage B! stage C ? a: ! stage D A B stage másodlagos output-ját irányítjuk a D stage-re.

2. a pipeline végén, ekkor a másodlagos input-ot kötjük össze pipe (end ?) stage A! a: stage B! stage C ? stage D ! a: A D stage output-ja a B stage másodlagos input-ja.

3. középen, ekkor az input-ot és az output-ot is összekötjük. pipe (end ?) stage A! a: stage B! stage C ? stage D ! a: ! stage E A D stage output-ja a B stage másodlagos input-ja, a B stage másodlagos output-ja pedig az E stage elsõdleges input-ja.

pl.: 'pipe (endchar ?) < test data a ! a: locate /BOB/ !> bob data a', '? a: ! > notbob data a' A locate elõtti a: a címke definíció, a ? utáni a: pedig a hivatkozás. Itt a locate másodlagos output stream-jét irányítjuk a > stage-re.

Fanout

Az elsõdleges input stream-jén lévõ összes rekordot változatlanul átmásolja az output stream-jeire.

Példa: Ebben a példában három output stream-et használunk:

   'pipe (endchar ?)',
   '< test data ! a: fanout ! locate 36.4 /1821/ !> 1821 data a',
   '? a: ! locate 21.4 /EXEC/ ! > exec data a',
   '? a: ! locate 45.2 /NY/ ! > ny data a'
   

Faninany

Az összes input stream-jén lévõ rekordot átmásolja az elsõdleges output stream-jére. Mindíg arról az input stream-rõl másol, aminek éppen van rekordja.

Példa: Az elsõ locate másodlagos output stream-jén lévõ rekordokból a második locate a SCRIPT file típusúakat választja ki, és a faninany az elsõdleges és másodlagos input stream-jén lévõ rekordokat kiírja a wanted files-ba.

   'pipe (endchar ?) cms listfile * * a (noheader !',
   'a:locate 10.5 /EXEC / ! f:faninany ! > wanted files a ?',
   'a: ! locate 10-16 /SCRIPT / ! f:'
 
   

Fanin [stream azonosító]

Annyiban különbözik a Faninany-tól, hogy megvárja, míg egy input stream-jén lévõ összes rekodot át tudja másolni az elsõdleges output stream-re, és csak ezután kezd egy következõ input stream-rõl olvasni. A stream azonosítóval lehet megadni, hogy melyik stream-ekrõl olvasson. pl.: ! f:fanin 0 4 2 ! , ekkor a 0 4 2 azonosítójú stream-ekrõl ebben a sorrendben olvas az 1 és 3-ról pedig nem olvas.

Overlay [SPACE!karakter]

Ez a stage parancs olvas minden input stream-jérõl egy rekordot, és ezekbõl elõállít egy output rekordot, amit az elsõdleges output stream-jére ír. Az output rekord egyes pozícióira azt a karakaktert írja amelyik a legnagyobb számú input stream megfelelõ pozícióján van. pl.: 0.stream-en:XXXXXX 1.stream-en:AA AA , ekkor az output stream-en az AAXAAX rekord lesz. Alapértelmezés szerint azon a pozíción, ahol space van ott meghagyja az kisebb számú stream-en lévõ karaktert. Ha a space helyett megadunk egy másik karaktert, akkor ahol olyat talál ott nem helyettesít. Példa:
   'pipe (end ?) < elso file a ! a:overlay ! new file a',
   '? < masodik file a ! a:'
 
   'pipe (end ?) literal alma ! a:overlay a ! console',
   '? literal baab ! a:'
   

Merge

Ezt a stage parancsot rekordok összefésülésére lehet használni. Az output stream-re kerülõ rekordok akkor lesznek rendezettek, ha az összes input stream-en rendezve voltak. Megadhatók oszloptartományok is, ekkor nem az egész rekordot veszi figyelembe.

Példa: Az a és c filemodként accessált diszkek tartalmát összefésüli:

   'pipe (end ?) cms listfile * * a! sort ! g:merge ! console ?',
   'cms listfile * * c ! sort ! g:'
   

Lookup

Az elsõdleges input stream-jén lévõ rekordokat összehasonlítja a másodlagos input stream-jén lévõkkel és az egyezõ és nem egyezõ rekodokat más output stream-re írja. Elõször beolvassa a másodlagos input stream-jén lévõ rekordokat (master), utána veszi az elsõdleges input stream-en lévõket (detail) és összehasonlítja a master rekordokkal. Amennyiben talál egyezõ master rekordot, akkor a detail rekordot kiírja az elsõdleges output stream-re, ellenkezõ esetben a másodlagos output stream-re. Miután az összes detail rekordot feldolgozta, kiíja a harmadlagos output stream-re azokat a master rekordokat, amelyekhez nem voltak egyezõ detail rekordok.