Unix: Extensión de un fichero Unix

En esta ocasión vamos a ver cómo podemos hacer con un script de Unix una tarea que en realidad también podemos hacer con SAS. Se trata de renombrar ficheros *.zip a *.zip.old, en este caso modificando su extensión. Para ello, debemos poder extraer las dos partes del nombre de un fichero: el nombre y la extensión.

FICHERO="${i%%.*}"
EXTENSION=$([[ "$i" = *.* ]] && echo "${i#.}" || echo "${i##.}")

Si queremos procesar todos los ficheros zip de un directorio para renombrarlos recursivamente a zip.old (por ejemplo) podemos usar el siguiente script. Lo primero que hace es listar los ficheros que tienen zip en su nombre (o extensión). Luego revisa, para cada uno de ellos, cual es exactamente su extensión, y si finalmente tienen extensión zip los renombra (con mv) a *.zip.old:

for i in $(ls -1 | grep .zip);
do FICHERO="${i%%.*}";
EXTENSION=$([[ "$i" = *.* ]] && echo "${i#.}" || echo "${i##.}");
if [ "$EXTENSION" == "zip" ];
then mv $FICHERO.zip $FICHERO.zip.old;
fi;
done

Este script puede ser llamado también desde SAS para hacer esa misma tarea con el comando X:

x"for i in $(ls -1 | grep .zip); do FICHERO="${i%%.*}"; EXTENSION=$([[ "$i" = *.* ]] && echo "${i#.}" || echo "${i##.}"); if [ "$EXTENSION" == "zip" ]; then mv $FICHERO.zip $FICHERO.zip.old; fi; done";

Número de registros en una tabla

Existen varias formas de determinar el número de registros o observaciones en una tabla. Hay van algunas:

Lo podemos hacer dentro de un proc sql guardando la cuenta de registros de la query en una variable con el comando into:

proc sql noprint;
    select count(*) into :nobs1
    from SASHELP.CARS;
quit;
%put &=nobs1;

La segunda opción es con un paso data utilizando el parámetro end en la tabla de entreda que (en el ejemplo siguiente) asigna un valor True a «eof» en caso de que se haya llegado al último registro de la misma. En ese momento, en el último registro, si consultamos qué valor toma la variable _N_ y lo guardamos en la variable «nobs2», podremos obtener el número de registros.

data _null_;
    set SASHELP.CARS end=eof;
    if eof then call symput('nobs2',_N_);
run;
%put &=nobs2;

Utilizando un stream de datos tenemos un atributo que podemos consultar, NOBS, que nos da el valor que estamos buscando. NOBS da como resultado el número de registros tras el where que hayamos aplicado a la tabla. Si queremos obtener el número de registros sin teneer en cuenta los filtros podemos utilizar NLOBS.

%let dsid = %sysfunc(open(SASHELP.CARS));
data _null_;
    %let nobs3a =%sysfunc(attrn(&dsid,NOBS));
    %let nobs3b =%sysfunc(attrn(&dsid,NLOBS));
run;
%let rc = %sysfunc(close(&dsid));
%put &=nobs3a;
%put &=nobs3b;

Existe también el atributo NVAR que indica el número de variables.

La última opción que se me ocurre es utilizando el proc contents para utilizar el campo NOBS de la tabla de salida. Aquí también existe el campo VARNUM cuyo máximo es el número de variables de la tabla. Finalmente leemos el primer registro de la tabla SALIDA con inbos=1 y asignamos el valor a una macrovariable:

proc contents data=SASHELP.CARS 
    out=SALIDA (keep=nobs) noprint;
run;

proc sql noprint inobs=1;
    select nobs into :nobs4
    from SALIDA;
quit;
%put &=nobs4;