miércoles, 25 de abril de 2012

Utilidades REXX III: eliminar ficheros XXX.*

En esta ocasión os traemos una utilidad en REXX para el caso de querer borrar todos los ficheros que empiecen por una determinada cadena.
Por ejemplo, queremos borrar todos los ficheros que se encuentren migrados de la aplicación APL y cuya nomenclatura sería algo así:
APL.NOMBRE.FICHERO

Podríamos ir uno por uno, pero según la cantidad de ficheros que haya podría llevarnos su tiempo...

No vamos a entrar en lo que significa el código REXX, pues se trata de desribir el uso de la utilidad, y no el código en sí. Quizás algún día nos metamos con el REXX pero de momento ya tenemos bastantes frentes abiertos!!

El código al completo debemos agradecérselo a los compañeros de www.ibmmainframes.com que son los que lo han compartido.
Gracias!!

JCL:

//STEP0020 EXEC PGM=IKJEFT01,DYNAMNBR=256,
//         PARM='NOMBREPGM SCAN DASD TAPE MIGR'
//* PARM VALUES - SCAN - LIST ONLY
//*             - RUN - PROCESS REQUESTS - DELETE OR HSM
//*             - DASD - LIST/DELETE DASD DATASETS
//*             - MIGR - LIST/DELETE MIGRATED DATASETS
//*             - TAPE - LIST/DELETE TAPE DATASETS
//*             - RCALL - LIST/RECALL SELECTED DATASETS
//*             - ARCH - LIST/MIGRATE SELECTED DATASETS TO ML1
//*             - ARCH2 - LIST/MIGRATE SELECTED DATASETS TO ML2
//SYSEXEC  DD DSN=MI.LIBRERIA.REXX,DISP=SHR
//SYSOUT   DD SYSOUT=*
//SYSTSPRT DD SYSOUT=*
//SYSTSIN  DD DUMMY
//DATASETS DD *
P390A.BORRAR.**
/*
//EXCLUDE DD *
P390A.BORRAR.ESTENO
/*


Como veis el JOB incluye varias opciones:
Opción 1:
SCAN --> Lista en la salida (SYSOUT) los nombres de los ficheros encontrados.
RUN --> Ejecuta la acción elegida en opción 2 para los ficheros seleccionados (puede ser eliminar, migrar o "desmigrar").


Opción 2:
DASD --> Indica ficheros DASD
MIGR --> Indica ficheros migrados
TAPE --> Indica ficheros en cinta
RCALL --> Hace un RCALL de los ficheros seleccionados (los "desmigra")
ARCH --> Migra los ficheros seleccionados a ML1
ARCH2 --> Migra los ficheros seleccionados a ML2


En DATASETS indicaremos el prefijo de los ficheros a tratar. En nuestro caso P390A.BORRAR.**
Si quisiésemos mantener alguno de los ficheros (no queremos que se eliminen) lo indicaríamos en EXCLUDE con el nombre completo. En nuestro caso hemos indicado:
P390A.BORRAR.ESTENO

Al inicio del paso veréis que hemos indicado como parámetro (PARM) el nombre de nuestro programa REXX (NOMBREPGM). Además como opciones hemos indicado SCAN para que sólo nos liste los ficheros, y DASD, TAPE y MIGR para que liste los ficheros en esos estados.
En el SYSEXEC hemos indicado la librería donde se encuentra nuestro programa (MI.LIBRERIA.REXX).

Un ejemplo de lo que mostraría por SYSTPRT sería:


Podemos ejecutar una segunda vez con la opción RUN en lugar de SCAN y veríamos en el SYSTPRT:


Habiéndose borrado los ficheros que indica.

Lo hemos probado y podemos decir que funciona a la perfección. Esperamos que os sea útil.

Programa:

/* REXX ** INVOKE CSI VIA BATCH REXX PROCESS
** LIST OR DELETE ALL ENTRIES FOR GIVEN DSN PATTERNS
ALSO TO FILTER BY DASD TAPE OR MIGR */
ARG RUNTYP UNIT
IF RUNTYP <> "RUN" THEN RUNTYP = "SCAN"
IF POS('MIGR',UNIT) > 0 & POS('RCALL',UNIT) > 0 THEN DO
   SAY " "
   SAY "RECALL AND HDELETE BOTH SPECIFIED FOR MIGRATED DATASETS"
   SAY "EXIT REURN CODE 16 *** EXIT RETURN CODE 16 "
   EXIT(16)
END
 "EXECIO * DISKR EXCLUDE ( STEM EXC. FINIS"
 DO A = 1 TO EXC.0
    IF POS('*',EXC.A) > 0 THEN DO       EXCLDIT.A = STRIP(SUBSTR(EXC.A,1,POS('*',EXC.A)-1))
      GEN.A = "Y"
    END
    ELSE DO       EXCLDIT.A = STRIP(EXC.A)
      GEN.A = "N"
    END
 END
 "EXECIO * DISKR DATASETS ( STEM CAT. FINIS"
 DO KCNT = 1 TO CAT.0
 KEY = SUBSTR(CAT.KCNT,1,44)
MODRSNRC = SUBSTR(' ',1,4)
CSIFILTK = SUBSTR(KEY,1,44)
CSICATNM = SUBSTR(' ',1,44)
CSIRESNM = SUBSTR(' ',1,44)
CSIDTYPS = SUBSTR(' ',1,16)
CSICLDI = SUBSTR('Y',1,1)
CSIRESUM = SUBSTR(' ',1,1)
CSIS1CAT = SUBSTR(' ',1,1)
CSIRESRV = SUBSTR(' ',1,1)
CSINUMEN = '0002'X
CSIFLD1 = 'VOLSER '
CSIFLD2 = 'DEVTYP '
CSIOPTS = CSICLDI || CSIRESUM || CSIS1CAT || CSIRESRV
CSIFIELD = CSIFILTK || CSICATNM || CSIRESNM || CSIDTYPS || CSIOPTS
CSIFIELD = CSIFIELD || CSINUMEN || CSIFLD1 || CSIFLD2
WORKLEN = 4096
DWORK = '00001000'X || COPIES('00'X,WORKLEN-4)
RESUME = 'Y'
CATNAMET = SUBSTR(' ',1,44)
DNAMET = SUBSTR(' ',1,44)
DO WHILE RESUME = 'Y'
 ADDRESS LINKPGM 'IGGCSI00 MODRSNRC CSIFIELD DWORK'
 RESUME = SUBSTR(CSIFIELD,150,1)
 USEDLEN = C2D(SUBSTR(DWORK,9,4))
 POS1=15
 DO WHILE POS1 < USEDLEN
   IF SUBSTR(DWORK,POS1+1,1) = '0'
    THEN DO
         CATNAME=SUBSTR(DWORK,POS1+2,44)
         IF CATNAME <> CATNAMET THEN
           DO
             CATNAMET = CATNAME
           END
         POS1 = POS1 + 50
         END
    DNAME = SUBSTR(DWORK,POS1+2,44)
    PRO = "Y"
    DO ZZ = 1 TO EXC.0
      EXCLDLN = LENGTH(EXCLDIT.ZZ)
      IF GEN.ZZ = "N" THEN DO
        IF STRIP(DNAME) = STRIP(EXCLDIT.ZZ) THEN PRO = "N"
      END
      ELSE DO
        IF STRIP(LEFT(DNAME,EXCLDLN)) = STRIP(EXCLDIT.ZZ) THEN PRO = "N"
      END
    END
    IF SUBSTR(DWORK,POS1+1,1) = 'C' THEN DTYPE = 'CLUSTER '
     ELSE
      IF SUBSTR(DWORK,POS1+1,1) = 'D' THEN DTYPE = 'DATA '
     ELSE
      IF SUBSTR(DWORK,POS1+1,1) = 'I' THEN DTYPE = 'INDEX '
     ELSE
      IF SUBSTR(DWORK,POS1+1,1) = 'A' THEN DTYPE = 'NONVSAM '
     ELSE
      IF SUBSTR(DWORK,POS1+1,1) = 'H' THEN DTYPE = 'GDS '
     ELSE
      IF SUBSTR(DWORK,POS1+1,1) = 'B' THEN DTYPE = 'GDG '
     ELSE
      IF SUBSTR(DWORK,POS1+1,1) = 'R' THEN DTYPE = 'PATH '
     ELSE
      IF SUBSTR(DWORK,POS1+1,1) = 'G' THEN DTYPE = 'AIX '
     ELSE
      IF SUBSTR(DWORK,POS1+1,1) = 'X' THEN DTYPE = 'ALIAS '
     ELSE
      IF SUBSTR(DWORK,POS1+1,1) = 'U' THEN DTYPE = 'UCAT '
     ELSE
      DTYPE = ' '
      POS1 = POS1 + 46
      NUMVOL = C2D(SUBSTR(DWORK,POS1+4,2))/6
      POS2 = POS1+8
      DO I=1 TO NUMVOL
        VOLSER.I = SUBSTR(' ',1,6)
      END
      DO I = 1 TO NUMVOL
        VOLSER.I = SUBSTR(DWORK,POS2,6)
        POS2 = POS2 + 6
      END
      IF NUMVOL > 1 THEN MVL = '+'
        ELSE
        MVL = ' '
      DEVTY1 = SUBSTR(DWORK,POS2,4)
      DEVTY2 = C2X(DEVTY1)
      IF SUBSTR(DEVTY2,5,2) = '20' THEN DELDEV = 'DASD'
        ELSE
          IF SUBSTR(DEVTY2,5,2) = '80' THEN DELDEV = 'TAPE'
            ELSE
              DELDEV = 'XXXX'
      IF DELDEV = 'DASD' THEN MIGLEV = ' ML1'
        ELSE
          MIGLEV = ' ML2'
      IF DNAMET <> DNAME THEN
      DO
        DNAMET=DNAME
        DNAM2 = STRIP(DNAME)
        IF DTYPE = 'GDG' | DELDEV = 'XXXX' THEN PRO = 'N'
        IF PRO = "Y" THEN DO
          IF VOLSER.1 = 'MIGRAT' THEN
            DO
             IF POS('MIGR',UNIT) > 0 | POS('RCALL',UNIT) > 0 THEN DO
               IF RUNTYP = "RUN" THEN
               DO
                 IF POS('MIGR',UNIT) > 0 THEN DO
                   SAY " HDEL FOR "DNAM2
                       " HDELETE '"DNAM2"'"
                 END
                 ELSE IF POS('RCALL',UNIT) > 0 THEN DO
                   SAY " HRECALL FOR "DNAM2
                       " HRECALL '"DNAM2"'"
                 END
              END
          ELSE
            SAY COPIES(' ',8) DTYPE DNAME VOLSER.1 MVL MIGLEV
          END
        END
        ELSE IF VOLSER.1 <> 'MIGRAT' THEN
          DO
           IF DTYPE = 'CLUSTER' & POS('DASD',UNIT) > 0 THEN DO
             IF RUNTYP = "RUN" THEN DO
                " DELETE '"DNAM2"'"
             END
             ELSE
               SAY COPIES(' ',8) DTYPE DNAME VOLSER.1 MVL DELDEV
             END
          ELSE DO
            IF DELDEV = 'TAPE' & POS('TAPE',UNIT) > 0
             THEN
             DO
               IF RUNTYP = "RUN" THEN
                 DO
                    " DELETE '"DNAM2"' NOSCRATCH "
                 END
               ELSE
                 SAY COPIES(' ',8) DTYPE DNAME VOLSER.1 MVL DELDEV
            END
           IF DELDEV = 'DASD' & POS('DASD',UNIT) > 0 ,
            & VOLSER.1 <> 'MIGRAT' THEN
            DO
             IF RUNTYP = "RUN" THEN
              DO
               " DELETE '"DNAM2"'"
              END
             ELSE
              SAY COPIES(' ',8) DTYPE DNAME VOLSER.1 MVL DELDEV
            END
           IF DELDEV = 'DASD' & POS('ARCH',UNIT) > 0 ,
            & VOLSER.1 <> 'MIGRAT' THEN
            DO
             IF SUBSTR(UNIT,POS('ARCH',UNIT)+4,1) = '2'
              THEN ML = "ML2"
              ELSE ML = ""
             IF RUNTYP = "RUN" THEN
              DO
               SAY COPIES(' ',8) DTYPE DNAME VOLSER.1 MVL DELDEV
                   " HMIG '"DNAM2"'" ML
              END
             ELSE
               SAY COPIES(' ',8) DTYPE DNAME VOLSER.1 MVL DELDEV
            END
         END
       END
    END
    POS1 = POS1 + C2D(SUBSTR(DWORK,POS1,2))
  END
END
END
END

5 comentarios:

Anónimo dijo...

Lo probe en un mainframe y no me funciona,tira el siguiente error

1 18 +++ DO EXCLDIT.A = STRIP(EXC.A)
IRX0041I Error running REXXDESM, line 18: Bad arithmetic conversion
READY
END
alguien tiene idea que puede ser? saludos

Mauricio Vega dijo...

fijate que puede ser que estes pasando mal un parametro.
está esperando algo de tipo AAAA y lo que recibe es de tipo 11111 o no te coincide algun nombre. Yo lo corrí y anda. Hay que meterle mano, pero lo podes hacer andar...

Mauricio Vega dijo...

por otro lado, yo necesito manejar cadena de textos para usar files. Files del tipo xxxxxxx.aaaaa.zzzzz.hhhhhh que pueden tener más o menos calificadores. 4 ó 5. a esos preguntarles por ejemplo el tamaño y mostrarlos en un listado. eso ya me sirve. me bloquie con algo. se me subio una idea al tanque y no puedo avanzar. gracias.

Mari Villar Blasco dijo...

Buenas! Me podéis indicar por favor qué significa '00001000'X??? En este contexto o cuando se compara con una variable en un IF? GRACIAS!

Tallian dijo...

Hola Mari.
La X indica que el valor que está entre las comillas está en formato hexadecimal, es decir:
0010
0000
Como en un INCLUDE:
INCLUDE COND=(55,4,BI,GE,X'00001000')