Walk a directory/Recursively: Difference between revisions

Undo revision 346953 by Rkriesel (talk)
(Undo revision 346954 by Rkriesel (talk))
(Undo revision 346953 by Rkriesel (talk))
Line 1,375:
return tPaths
end pathsForPatternAndDirectory
 
=={{header|Lua}}==
Lua itself is extremely spartanic as it is meant for embedding. As lfs (LuaFileSystem) is about as standard an extension as it gets, we use that.
<lang Lua>local lfs = require("lfs")
 
-- This function takes two arguments:
-- - the directory to walk recursively;
-- - an optional function that takes a file name as argument, and returns a boolean.
function find(self, fn)
return coroutine.wrap(function()
for f in lfs.dir(self) do
if f ~= "." and f ~= ".." then
local _f = self .. "/" .. f
if not fn or fn(_f) then
coroutine.yield(_f)
end
if lfs.attributes(_f, "mode") == "directory" then
for n in find(_f, fn) do
coroutine.yield(n)
end
end
end
end
end)
end
 
-- Examples
-- List all files and directories
for f in find("directory") do
print(f)
end
 
-- List lua files
for f in find("directory", function(self) return self:match("%.lua$") end) do
print(f)
end
 
-- List directories
for f in find("directory", function(self) return "directory" == lfs.attributes(self, "mode") end) do
print(f)
end</lang>
 
Lua provides functions such as os.execute([command]) and io.popen(prog [, mode]). Below an example for Windows users having io.popen at their disposal. Mind you, it may pop-up a command window.
<lang Lua>-- Gets the output of given program as string
-- Note that io.popen is not available on all platforms
local function getOutput(prog)
local file = assert(io.popen(prog, "r"))
local output = assert(file:read("*a"))
file:close()
return output
end
 
-- Iterates files in given directory
local function files(directory, recursively)
-- Use windows" dir command
local directory = directory:gsub("/", "\\")
local filenames = getOutput(string.format("dir %s %s/B/A:A", directory, recursively and '/S' or ''))
-- Function to be called in "for filename in files(directory)"
return coroutine.wrap(function()
for filename in filenames:gmatch("([^\r\n]+)") do
coroutine.yield(filename)
end
end)
end
 
-- Walk "C:/Windows" looking for executables
local directory = "C:/Windows"
local pattern = ".*%.exe$" -- for finding executables
for filename in files(directory, true) do
if filename:match(pattern) then
print(filename)
end
end</lang>
 
7,804

edits