[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: FINDFILE and Unix



Findfile on unix is rather more of a direct invocation of ls than
you might imagine.

E.g., to get only files and directories in a given directory without
looking in subdirectories...

files = findfile('-d somedirectory/*')

I.e., you can specify the -d qualifier for the ls command -- and
as far as I know any other ls qualifier, e.g., you can use -l to get
the long directory listing...

Of course I am using an archaic version of IDL 5.0 on a DEC alpha
and this may have been fixed.

Another couple of gotchas...  You may run into the Unix limit on the
length of a command when searching directories with many files.
Also, when searching multiple subdirectories  you can find nasty
little directory headers in your file list (as well as blank separators).

I do hope these have been fixed in later versions of IDL but you
may want to check.

	Regards,
	Tom McGlynn

Doug Reynolds wrote:
> 
> I recently had some problems with the FINDFILE function.  First of all, the
> Online Help documentation contains an error:
> 
>    Under UNIX, to refer to all of the files in a directory only, use
>    FINDFILE('/File_Specification/*.*'). To include all the files in any
>    subdirectories, use FINDFILE('/File_Specification/*')
> 
> However, under Unix, a call with "*.*" omits any files that do not include "."
> in their name.  In addition, searching for "*.*" does not prevent searching
> through subdirectories - if a directory name contains ".", FINDFILE will
> include any files within it.
> 
> Now, the reason I was looking through the documentation in the first place is
> that FINDFILE can not do what I was trying to do.  We have a directory that
> contains 97 subdirectories starting with "f" - "f300", "f301", "f302", etc.  I
> wanted to get a list of all of these subdirectories.  Here is what happened:
> 
>         IDL> files = findfile ("/users/username/f*")
>         IDL> help, files
>         FILES               STRING    = Array[1767]
> 
> The problem is that in addition to returning the directory names I wanted,
> FILES also included all the files and subdirectories in these directories.
> Unfortunately, under Unix, there is no way to make FINDFILE return a directory
> name without also including the contents.
> 
> My guess is that FINDFILE is just an interface to the "ls" command.  If so, I
> think it would be nice if a keyword could be added to make FINDFILE execute
> either "ls" or "ls -d", depending on whether or not the user wants to include
> subdirectory contents.  For example:
> 
>         files = findfile ("/users/airi/f*", /norecurse)
>         files = findfile ("/users/airi/f*", /recurse)
> 
> In the meantime, I have written a FINDFILE replacement, which I have included
> below.  On an OS other than Unix it just calls FINDFILE, but Unix users have
> the option of using a /RECURSE keyword to enable or disable subdirectory
> searches.  Any comments / feedback would be appreciated.
> 
> Doug Reynolds
> 
> ;+
> ; NAME:
> ;      llfindfile
> ; PURPOSE:
> ;      Replacement for IDL's FINDFILE function, which does not work properly
> ;      under Unix.
> ; EXAMPLES:
> ;      1. List all files ending with .dat in the current directory:
> ;         files = llfindfile ('*.dat')
> ;      2. List all files in the entire /users/airi hierarchy, and return
> ;         the number of entries:
> ;         files = llfindfile ('/users/airi', /recurse, count = count)
> ; CALLING SEQUENCE:
> ;      files = llfindfile (filespec, [/recurse] [,count=entries])
> ; INPUTS:
> ;      path         The file specification to match (can include wildcards)
> ; OPTIONAL INPUTS:
> ; KEYWORD PARAMETERS:
> ;      /help        Prints this header
> ;      /recurse     If set, causes the search to include files and
> ;                   subdirectories within matched directories
> ; OUTPUTS:
> ; OPTIONAL OUTPUTS:
> ;      count        Returns the number of files found
> ; COMMON BLOCKS:
> ; SIDE EFFECTS:
> ;      IDL's FINDFILE appends a colon to a name if it is a directory; this
> ;      routine appends a '/'.
> ; RESTRICTIONS:
> ; PROCEDURE:
> ; MODIFICATION HISTORY:
> ;      000131  DSR  Written.
> ;-
> function llfindfile, path, recurse = recurse, count = count, help = help
> 
> ;   Help
> 
>    if keyword_set(help) then begin
>       doc_library, 'llfindfile'
>       return, 0
>    endif
> 
>    if !version.os_family ne 'unix' then begin
>       return, findfile (path, count = count)
>    endif else begin
>       if n_elements (path) eq 0 then command = 'ls -F' else begin
>          if not keyword_set (recurse) then command = 'ls -Fd ' else $
>            command = 'ls -F '
>          command = command + path
>       endelse
>       spawn, command, result
>       count = n_elements (result)
>       return, result
>    endelse
> end