J'ai besoin d'une liste de répertoires dans LUA
Supposons que j'ai un chemin de répertoire comme "C:\Program Files"
J'ai besoin d'une liste de tous les dossiers dans ce chemin particulier et comment rechercher un dossier particulier dans cette liste.
Exemple
Besoin d'une liste de tous les dossiers dans le chemin "C:\Program Files"
Voici le nom du dossier dans le chemin ci-dessus
dossier 456 789
Besoin d'obtenir ce qui précède dans une liste, puis de rechercher une chaîne particulière comme le dossier 456 dans le dossier 456 789 uniquement.
J'ai essayé le code ci-dessous. Quelque chose qui me manque ci-dessous: -
local function Loc_Lines( str )
--
local ret= {} -- 0 lines
while str do
local _,_,line,tail= string.find( str, "(.-)\n(.+)" )
table.insert( ret, line or str )
str= tail
Print (str)
end
return ret
end
local function Loc_ShellCommand( cmd )
--
local str= nil
--
local f= io.popen( cmd ) -- no command still returns a handle :(
if f then
str= f:read'*a'
Print(str)
f:close()
end
if str=="" then -- take no output as a failure (we can't tell..)
Print("hi")
str= nil
end
-- Remove terminating linefeed, if any (eases up one-line analysis)
--
if str then
if string.sub( str, -1 ) == '\n' then
str= string.sub( str, 1, -2 )
end
end
return str
end
local function Loc_DirCmd( cmd )
Print(cmd)
local str= Loc_ShellCommand( cmd )
return Loc_Lines(str)
end
local function Loc_DirList( dirname )
local ret= {}
local lookup= {}
local tbl= Loc_DirCmd( "dir /AD /B "..dirname ) -- only dirs
-- Add slash to every dir line
--
for i,v in ipairs(tbl) do
table.insert( ret, v..'\\' )
lookup[v]= true
end
-- Return with forward slashes
--
if true then
for i=1,table.getn(ret) do
ret[i]= string.gsub( ret[i], '\\', '/' )
Print (ret[i])
end
end
return ret
end
Loc_DirList("C:\\Program Files\\")
Prenez le chemin facile, installez lfs. Utilisez ensuite les constructions suivantes pour trouver ce dont vous avez besoin:
require'lfs'
for file in lfs.dir[[C:\Program Files]] do
if lfs.attributes(file,"mode") == "file" then print("found file, "..file)
elseif lfs.attributes(file,"mode")== "directory" then print("found dir, "..file," containing:")
for l in lfs.dir("C:\\Program Files\\"..file) do
print("",l)
end
end
end
notez qu'une barre oblique inverse est égale à [[\]]
équivaut à "\\"
, et que dans windows/est également autorisé s'il n'est pas utilisé sur le cmd lui-même (corrigez-moi si je me trompe sur celui-ci).
Je déteste devoir installer des bibliothèques (en particulier celles qui veulent que j'utilise des packages d'installation pour les installer). Si vous cherchez une solution propre pour une liste de répertoires sur un chemin absolu à Lua, ne cherchez pas plus loin.
Sur la base de la réponse fournie par sylvanaar, j'ai créé une fonction qui renvoie un tableau de tous les fichiers pour un répertoire donné (chemin absolu requis). C'est ma mise en œuvre préférée, car elle fonctionne sur toutes mes machines.
-- Lua implementation of PHP scandir function
function scandir(directory)
local i, t, popen = 0, {}, io.popen
local pfile = popen('ls -a "'..directory..'"')
for filename in pfile:lines() do
i = i + 1
t[i] = filename
end
pfile:close()
return t
end
Si vous utilisez Windows, vous aurez besoin d'avoir un client bash installé pour que la commande 'ls' fonctionne - alternativement, vous pouvez utiliser la commande dir fournie par sylvanaar:
'dir "'..directory..'" /b /ad'
for dir in io.popen([[dir "C:\Program Files\" /b /ad]]):lines() do print(dir) end
*Pour les fenêtres
Les sorties:
Adobe
Bitcasa
Bonjour
Business Objects
Common Files
DVD Maker
IIS
Internet Explorer
iPod
iTunes
Java
Microsoft Device Emulator
Microsoft Help Viewer
Microsoft IntelliPoint
Microsoft IntelliType Pro
Microsoft Office
Microsoft SDKs
Microsoft Security Client
Microsoft SQL Server
Microsoft SQL Server Compact Edition
Microsoft Sync Framework
Microsoft Synchronization Services
Microsoft Visual Studio 10.0
Microsoft Visual Studio 9.0
Microsoft.NET
MSBuild
...
Chaque fois que vous parcourez la boucle, vous obtenez un nouveau nom de dossier. J'ai choisi de l'imprimer comme exemple.
Je n'aime pas non plus installer des bibliothèques et je travaille sur un appareil embarqué avec moins de puissance de mémoire qu'un PC. J'ai découvert que l'utilisation de la commande "ls" entraînait une perte de mémoire. J'ai donc créé une fonction qui utilise 'find' pour résoudre le problème.
De cette façon, il a été possible de maintenir une utilisation régulière de la mémoire et de boucler tous les fichiers de 30k.
function dirLookup(dir)
local p = io.popen('find "'..dir..'" -type f') --Open directory look for files, save data in p. By giving '-type f' as parameter, it returns all files.
for file in p:lines() do --Loop through all files
print(file)
end
end
IIRC, obtenir la liste des répertoires n'est pas possible avec le stock Lua. Vous devez écrire vous-même du code de colle ou utiliser LuaFileSystem . Ce dernier est probablement le chemin de moindre résistance pour vous. Une analyse rapide de la documentation montre lfs.dir()
qui vous fournira un itérateur que vous pouvez utiliser pour obtenir les répertoires que vous recherchez. À ce stade, vous pouvez ensuite faire votre comparaison de chaînes pour obtenir les répertoires spécifiques dont vous avez besoin.
Vous installez et utilisez également le module ' chemins '. Ensuite, vous pouvez facilement le faire comme suit:
require 'paths'
currentPath = paths.cwd() -- Current working directory
folderNames = {}
for folderName in paths.files(currentPath) do
if folderName:find('$') then
table.insert(folderNames, paths.concat(currentPath, folderName))
end
end
print (folderNames)
- Cela imprimera tous les noms de dossier
Facultativement, vous pouvez également rechercher des noms de fichiers avec une extension spécifique en remplaçant fileName:find('$')
par fileName:find('txt' .. '$')
Si vous exécutez sur une machine basée sur Unix, vous pouvez obtenir une liste de fichiers triée numériquement en utilisant le code suivant:
thePath = '/home/Your_Directory'
local handle = assert(io.popen('ls -1v ' .. thePath))
local allFileNames = string.split(assert(handle:read('*a')), '\n')
print (allFileNames[1]) -- This will print the first file name
Le deuxième code exclut également les fichiers tels que "." et '..'. Alors c'est bon d'y aller!
Ne pas analyser ls
, c'est mal! Utilisez à la place find
avec des chaînes terminées par zéro (sous linux):
function scandir(directory)
local i, t = 0, {}
local pfile = assert(io.popen(("find '%s' -maxdepth 1 -print0"):format(directory), 'r'))
local list = pfile:read('*a')
pfile:close()
for filename in s:gmatch('[^\0]+')
i = i + 1
t[i] = filename
end
return t
end
AVERTISSEMENT: cependant, comme réponse acceptée, cette approche pourrait être exploitée si le nom du répertoire contient '
dedans. Une seule solution sûre consiste à utiliser lfs
ou une autre bibliothèque spéciale.