Puede interesarnos tener directorios y subdirectorios en tablas SAS. Es decir, tabular el resultado de un lm en Unix o poner en una tabla el resultado de un dir de MS DOS / Windows. Ya tengo ejemplos publicados a este respecto:

Pero no está mal volver a poner un truco para analizar las posibilidades del INFILE + PIPE. Vamos a hacer un DIR de todo nuestro C:\ y sacar los archivos de mayor tamaño.
*ESTA ES LA INSTRUCCION DIR QUE EMPLEAMOS,
SUBDIRECTORIOS, AUTORES, ... (?dir);
filename df pipe "dir H:\ /S /O S /Q";
*CREAMOS UNA TABLA SAS CON EL RESULTADO DE
LA INSTRUCCIÓN MS DOS;
data ZZZ_ZZZ;
infile df pad;
input todo $300.;
if _n_=1 then delete;
run;

Tenemos una tabla SAS con el resultado de nuestro dir en una variable de texto todo de 300 bytes . Podemos extraer la información que deseamos trabajando con funciones de texto de SAS:
data archivos;
keep fecha archivo GIGAS autor;
set zzz_zzz;
format fecha ddmmyy10.;
fecha=input(substr(todo,1,10),ddmmyy10.);
GIGAS=compress(scan(todo,3," "),".")*1;
GIGAS=GIGAS/(1024**3);
autor=scan(todo,4," ");
archivo=substr(todo,60,100);
if fecha=. then delete;
if GIGAS=. then delete;
run;

La variable fecha tiene el formato ddmmyy10. y es el resultado de transformar parte de nuestra variable de texto todo a número y con input darle el formato de entrada adecuado, perfecto ejemplo de transformación de texto a fecha con SAS. El tamaño es la 3 parte de la cadena de texto que se obtiene con un dir, pero como lo tenemos en bytes lo transformamos a gigas. Para extraer parte de una cadena de texto con SAS empleamos la función SCAN, otro buen ejemplo es el autor que lo podemos encontrar en la cuarta posición. Recordamos: SCAN(todo,4,” “) -> busca en todo la cadena de texto que esté en cuarta posición cuando el delimitador es “ “ un espacio en blanco. Por último tenemos el nombre del archivo que es la última parte de la cadena todo que genera el dir de MS-DOS.
Buen ejemplo para recordar un par de temas que provocan un gran número de visitas a esta web. Ahora os dejo deberes, tenéis que obtener el directorio en el que se aloja el fichero. No es baladí el tema. A ver si sois capaces, yo lo tengo hecho pero es muy complejo y “poco elegante”. Espero que a alguno de vosotros se os ocurra un mejor método.

5 pensiamientos en “Trucos SAS. Más usos de INFILE y PIPE directorios en tablas SAS

  • José Antonio Gil Martín

    Si lo único que queremos es un fichero con dos columnas, una con el nombre del fichero y la otra con el nombre del directorio en el que está incluido, se puede ejecutar el siguiente código:

    filename dirresul pipe “dir C:\ /b /s” lrecl=32767 console=min;

    En en código anterior se ejecuta el comando dir con la opción /b para obtener una salida en formato simple.

    data dirsalida;
    infile dirresul truncover;
    input ruta $300.;
    run;

    En el siguiente paso data se calcula el largo de cada cadena y se busca desde el final de ella hasta encontrar el primer caracter ‘\’, hasta ahí se supone que tenemos el nombre del fichero y desde el primer caracter hasta la barra inclinada tenemos el nombre del directorio. Como de esta forma también salen en la variable fichero los nombres de los directorios le pongo el where en el fichero de salida para que solo seleccione los registros que en la variable fichero contengan un punto, suponiendo que todos los nombres de los ficheros incluyan su extensión.

    data dirsalida2(where=(fichero like ‘%.%’));
    set dirsalida;
    largo=length(ruta);
    posbarra=find(ruta, ‘\’, -largo);
    fichero=substr(ruta, posbarra+1);
    directorio=substr(ruta, 1, posbarra);
    keep fichero directorio;
    run;

    El proc freq nos muestra un listado del número de ficheros por subdirectorio.

    proc freq data=dirsalida2 order=freq;
    table directorio;
    run;

    Saludos

    Responder
  • rvaquerizo

    ¡Perfecto!

    Pensé que alguien iba a emplear retain a partir del código que yo puse. El truco estaba en el /b

    ¿La función find funciona en V8? No me suena haberla utilizado. Incluso tengo tengo la mía:

    http://analisisydecision.es/truco-sas-funcion-para-contar-caracteres/

    Responder
  • José Antonio Gil Martín

    Raúl la función find no está en V8 pero puedes usar el siguiente código que utiliza las funciones reverse, index y substr, que sí están disponibles en V8.

    data borrar(where=(fichero like ‘%.%’));
    set dirsalida;
    subdirectorio=reverse(substr(reverse(ruta), index(reverse(ruta), ‘\’)));
    fichero=reverse(substr(reverse(ruta), 1, index(reverse(ruta), ‘\’)-1));
    drop ruta;
    run;

    Primero la función reverse invierte la ruta, y después se obtiene el subdirectorio como la subcadena que va desde el primer símbolo ‘\’ hasta el final, y el nombre del fichero como la subcadena que va desde el primer caracter hasta el caracter anterior al primer símbolo ‘\’, por último se vuelve a aplicar reverse para dejar la ruta en su orden original.

    Saludos

    Responder
  • Noelia

    Tengo una duda, consigo cargar todos los ficheros de una ruta, es una tarea que va a ser diaria pero lo que me falta es tener el control de los ficheros que ya he cargado para no volverlos a cargar.
    Consigo crear una tabla con el nombre de los ficheros de la ruta a leer y tengo una tabla previa con los nombres de los ficheros que ya he cargado… entonces…¿como hago para que solo cargue o lea los datos de los ficheros que no he cargado con anterioridad?

    Gracias por adelantado!!

    Responder

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *