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:
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
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...
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.
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!
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')