Page 1 of 1

function for filelist with matching files

Posted: Fri Nov 21, 2003 10:27 pm
by HPW
The (directory) function gives back all files in a directory.

I would like a function like this:

(files "C:\temp\A*.txt")

which would return all matching text-files in that dir.

Posted: Sat Nov 22, 2003 9:33 am
by nigelbrown
try a function defined using directory and regex say:

(define (files d f) (filter (lambda (x) (regex f x)) (directory d)))

usage would be lke (files "c:/temp/" "[Aa][a-z]+\.txt")
that is first is the directory as a string the second is a regular expression as a string (not quite as friendly as filename wildcards but more powerful).
Filter works because will return nil if there is no match.

Regards
Nigel

Posted: Sat Nov 22, 2003 12:22 pm
by HPW
Thanks Nigel,

Nice and short. Have not thought enough about it. :-)
Have to test it with big files-counts.

Posted: Sat Nov 22, 2003 1:05 pm
by Lutz
On windows as long as you don't go via newlisp-tk but directly with newlisp.exe you also can do:

(exec "dir /b c:/*.txt")

Note, that the forward slash is Ok, /b will make sure that you only get filename info and exec will put all the filename strings nicely in a list just like 'directory'.

On Linux and other UNIXs this will work in both, newlisp-tk and streight newlisp:

(exec "ls /*.txt")

In any case I suspect that Nigels' suggestion will be the faster method and with less computing resorces, as it doesn't need to start a new shell process. Since 7.3.8 you also can write:

(filter (fn (x) (regex f x)) (directory d))

which makes it a tiny bit more readable and shorter (fn instead of lambda).

Lutz

Posted: Sat Nov 22, 2003 2:24 pm
by HPW
So this is the way to go:

(define (files fpath fpattern caseflag)(filter(fn (x)(regex fpattern x caseflag))(directory fpath)))

(files "c:/temp/" "^A.*\.mbi" 0)

When started from the tk-console the text-output speed of the console is the limiting factor when output sveral thousand file-names.
A more matching search-pattern return very fast the wanted files.

But why does enabling case-insensitiveness does not work:

Code: Select all

> (files "c:/Dba/preistab/" "^A.*\.mbi" 0)
("A0002.mbi" "A0010.mbi" "A0020.mbi" "A0030.mbi" "A0031.mbi")
> (files "c:/Dba/preistab/" "^a.*\.mbi" 0)
()
> (files "c:/Dba/preistab/" "^a.*\.mbi" 1)
()
> 
Changing the order of the calls changes the results.
Why do it not give the correct result every time?

Posted: Sat Nov 22, 2003 6:06 pm
by HPW
It seems to be a bug in regex.

Only when something in the search pattern is changed, it get a new result set. Only changing the case of a letter does not get it. When you change to another letter, the sensitive flag is processed correctly.

Code: Select all

(regex "^A.*\.mbi" "A0002.mbi" 0)
("A0002.mbi" 0 9)
> (regex "^a.*\.mbi" "A0002.mbi" 0)
nil
> (regex "^a.*\.mbi" "A0002.mbi" 1)
nil
> (regex "^A.*\.mbi" "A0002.mbi" 1)
("A0002.mbi" 0 9)
> (regex "^a.*\.mbi" "A0002.mbi" 1)
("A0002.mbi" 0 9)
> (regex "^a.*\.mbi" "A0002.mbi" 0)
("A0002.mbi" 0 9)
> 

Posted: Sat Nov 22, 2003 9:21 pm
by Lutz
The compiled regular expression pattern is cached internally and only recompiled, when changed for speed optimizations.

I have fixed this, so in the next version an options flag change will also trigger a pattern recompile.

Yes, the tk output console slows down the more it gets filled up, you may want to try out stuff sometimes by using newlisp.exe in a raw mode, if you have to watch huge output capacities; but I guess that TK is an integral part of your application?

Lutz