function for filelist with matching files

Started by HPW, November 21, 2003, 02:27:49 PM

Previous topic - Next topic

HPW

The (directory) function gives back all files in a directory.



I would like a function like this:



(files "C:tempA*.txt")



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

nigelbrown

#1
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

HPW

#2
Thanks Nigel,



Nice and short. Have not thought enough about it. :-)

Have to test it with big files-counts.
Hans-Peter

Lutz

#3
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

HPW

#4
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:



> (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?
Hans-Peter

HPW

#5
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.



(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)
>
Hans-Peter

Lutz

#6
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