Función FileFind modificada [Actualizada]

Todas los scripts relacionados con AMS.
Bueno, esta función es un FileFind que buscará todos aquellos archivos que coincidan con nuestra tabla de cadenas de búsqueda. Requiere la dll luafilesystem (lfs.dll):
--Globales
require"lfs";
function FileFind(sPath, tSearch, bSubFolders, bCaseSensitive, tToAdd, callback)
        local tS = (type(tSearch=="table")) and tSearch or {""};
        local bC = bCaseSensitive or false;
        if #tS > 0 then
                for x, y in pairs(tS) do
                        local a = (bC==true) and y or string.gsub(y, "(.)", function(s) return string.lower(s) end);
                        a = string.gsub(a, "(.)*(.)", function(s, sa) return "%b"..s..sa end);
                        a = string.gsub(a, "*(..)", function(s) return "%b"..s end);
                        a = string.gsub(a, "(..)(.)%.", function (s, ss) return (s=="%b") and s..ss.."." or s..ss.."%." end)
                        a = string.gsub(a, "^%.", "%%.")
                        tS[x] = string.gsub(a, "?", ".");
                end
        end
        return FileFindB(sPath, tS, bSubFolders, bC, tToAdd, callback);
end
function FileFindB(sPath, tSearch, bSubFolders, bCaseSensitive, tToAdd, callback)
        local tReturn = (type(tToAdd)=="table") and tToAdd or {};
        local tDirs = {};
        if lfs.chdir(sPath) then
                for x in lfs.dir(sPath) do
                        if x ~= "." and x ~= ".." then
                                if lfs.attributes(x, "mode") == "file" then
                                        for y, z in pairs(tSearch) do
                                                local a = (bCaseSensitive==false) and x or string.gsub(x, "(.)", function(s) return string.lower(s) end);
                                                if string.find(a, z) then
                                                        table.insert(tReturn, #tReturn+1, sPath.."\\"..x);
                                                        if callback ~= nil then
                                                                local b = callback(sPath.."\\"..x, #tReturn);
                                                                if not b then Application.ExitScript(); end
                                                        end
                                                end
                                        end
                                elseif lfs.attributes(x, "mode") == "directory" then
                                        if bSubFolders then
                                                table.insert(tDirs, #tDirs+1, sPath.."\\"..x);
                                        end
                                end
                        end
                end
                if #tDirs > 0 and bSubFolders then
                        for x, y in pairs(tDirs) do
                                FileFindB(y, tSearch, true, bCaseSensitive, tReturn, callback);
                        end
                end
                return (#tReturn>0) and tReturn or nil;
        else
                return nil;
        end
end
Se utiliza así:
local t1 = os.clock()
local tFiles = FileFind("C:\\Windows", {".dat", "*.dll", "s*.exe"}, true, false, nil);
if tFiles then
	Debug.ShowWindow(true);
	Debug.Print("Files: "..#tFiles.."\r\nTime: "..(os.clock()-t1).."\r\n"..ptbl(tFiles));--ptbl es una función para imprimir tablas
else
	Dialog.Message("", "NoFiles");
end
Siempre me gusta usar más las funciones que lua y sus módulos otorgan porque son mucho (pero muchísimo) más rápidas que las incorporadas en el AMS. También el uso del os.clock me gusta para determinar cuantos segundos y milisegundos tarda en realizar la búsqueda :D
:num1:
ceone, podrías revisar el porque cuando colocas dentro de tags lua algunos signos se cambian?
toy en ello... ;)
Thnx
creo que podría ser por el comando Hide, prueba de escribirlo de nuevo anulando el Hide. recuerdo que paso algo así hace tiempo... tengo la mente en otro mundo ahora jejeje :D
hoy mismo lo pruebo.

Mil gracias :friends:
el todopoderoso lua XD
Perdona, podrias ponerme la descarga la ultima version de la dll luafilesystem (lfs.dll)? Porque no la encuentro por ningun lado.

thx
Aca te dejo la dll: http://www.mediafire.com/?49jly4o1m9ual8c

Es increíble esta función, la estoy usando en un proyecto de búsqueda y filtrado de archivos y de 4.5seg me bajo el tiempo a sólo 1.5segundos siendo casí instantánea la búsqueda. Buscando y filtrando todas las dll de C:/ tardó sólo 58.7 segundos xD dejando muy atrás al buscador de windows jojojo.
Lo acabo de probar, la velocidad es asombrosa!!

Pero tiene varios fallos graves. El primero es que no busca la extension correctamente, es decir si yo busco la extension ZIP, encontrara cualquier cadena de texto que tenga la ruta de cualquier archivo como extension zip. Ejemplo:

C:\myzipfile.exe ---lo detecta como ZIP.

Esto causa que los wildcars no funcionen correctamente, por ejemplo a?.e* no muestra archivos con aX.exe por ejemplo, sino que muestra archivos como aXXXXXX.dll.

Tambien si es posible, me gustaria que me explicaras como hacer la funcion callback durante el FileFind (no después al cargar la tabla resultante de la dll).

Muchas gracias
Gracias, si note el fallo hace rato...La corrijo y la pongo en unos minutos junto con otra versión que tenga el callbackfunction. Casi no me agradan los callback a status.dialogs porque alentan el proceso, pero igual si es a un progress va de 10 ;) .
Muchas gracias!!

Entonces se podra utilizar sin problemas wildcars en el nombre de archivo y extension, no?

Lo del statusdlg es una putada, por eso comentaba en el otro post que seria genial algun plugin que sea capaz de hacer lo mismo pero en una pagina del proyecto. Porque sin mostrar el statusdlg las funciones que no tienen callback causan que se bloquee la aplicacion hasta que termina la funcion.
Venga, te comento así de rápido. Los comodines usuales son muy diferentes a los comodines del lua por lo que tuve que hacer un string.gsub (reemplazo) de caracteres en los miembros de la tabla de búsqueda. Por ejemplo, el comodín ? traducido a lua sería un simple . (punto) , por ello te mostraba archivos que tu no querías encontrar (pero para lua sí era válida la búsqueda).

Ahora, he hecho que los comodines * y ? signifiquen lo mismo a lua (un simple punto). La única forma en la que encontraría útil usar un * sería en encontrar la cadena de caractéres encontrados en una cadena como "abcdefgh" y buscar algo como "a*d" devolviendo "abcd". Pero para "*.exe" es será igual "?.exe" ó ".exe".

En resumen, buscar "h*.zip" ó "h?.zip" será lo mismo ;) .

Ahora sí, aca la función corregida:
--Revisar primer post
Pruebala y me comentas ;)

PD: para tu ejemplo de a?.e* (es igual a a?.e? y a*.e* ó a?.e ) puedes colocar ese término en la tabla de búsqueda y si te encontrará el archivo que comentabas "aX.exe"

PD: La primera función filtrará tus cadenas a buscar para asignarle los comodines correctos y la luego comienza la búsqueda ;) .
Hola

Muchas gracias por el nuevo script, pero sigue fallando. Por ejemplo "a?.c*" muestra archivos que no empiezan por "a" es decir; "dsfsfs.com" o "ertgs.cmd".

En cuanto a los comodines, el comodin de "?" se deberia reemplazar por un unico caracter, ejemplo; f?.exe seria ---> f1.exe o ff.exe. Si utilizamos otro "?" seria f??.exe y quedaria como f11.exe o frr.exe.

En cambio el comodin "*" permite cualquier cadena o ninguna, es decir; f*.exe seria ---> frgrgrgrg.exe o f.exe o f435345345345345345345345.exe.

Probare el nuevo callback (sPath, tSearch, bSubFolders, tToAdd, callback), la parte de tToAdd que permite?

Un saludo
Otra cosa, no consigo que busque en minúsculas y mayúsculas.

He cambiado la linea:
if string.find(x, z) then
--Por
if (String.Find(x, z, 1, false) ~= -1) then
Porque si busco, por ejemplo la extensión: *.ZIP no encuentra los archivos que acaben en extensión .zip en minúsculas.

Un saludo
aass escribió:Porque si busco, por ejemplo la extensión: *.ZIP no encuentra los archivos que acaben en extensión .zip en minúsculas.

eso es un error fácil de solucionar solo ay que añadir un filtro para que filtre mayúsculas y minúsculas... eso luego te lo solucionaran fácilmente...!

RECUERDA SIEMPRE QUE ESCRIBAS SCRIPTS USA EL COMANDO LUA
ok gracias.

He usado el comando LUA, pero me salian unos caracteres muy raros con porcentajes y demas, y por eso lo he quitado. (Quizas seria porque lo habia metido dentro de un HIDE).

Un saludo
se agradece !!
aass, sé como funcionan los comodines en windows pero para lua son diferentes por lo que tendré mejorar la función que realiza la conversión de éstos.

Una solución sería usar el String.Find del AMS para poder usar los comodínes de windows, pero aún así si buscas por ejemplo "a?.e*" encontraría archivos como "fa1.exe.001" ya que sólo buscan que el patrón a buscar se encuentre dentro de la cadena provista por la función. Ah y tendrías que quitar la primera función donde hago la conversión de comodínes :D .

Lo que te explicaba en el post anterior con relación a que hice que "?" y "*" funcionaran siempre como "?". Porque por ejemplo buscar "*.exe" era igual que "?.exe" ó ".exe" . Pero si tú lo que necesitas es un "f*.exe" para encontrar algo como "ffjklsdfjl.exe" entonces si tengo que modificar la función (tengo que usar un %bxy de lua) pero a veces no me daba el resultado que buscaba.

Acerca de mayúsculas o minúsculas, la función siempre hace diferencia ésto, no siendo igual "*.exe" a "*.EXE" ó "*.ExE" . Dime si quieres que la función sea insensible a mayúsculas y minúsculas ó que tenga ambas opciones ;) .

Por cierto, la función Callback envía los datos de archivo y número de archivos encontrados, sFile y nFiles respectivamente.

Hoy veré más a fondo los comodínes de esta función.