web-dev-qa-db-ja.com

Luaでディレクトリのリストを取得する方法

LUAのディレクトリのリストが必要です

「C:\ Program Files」というディレクトリパスがあるとします

その特定のパスにあるすべてのフォルダーのリストと、そのリスト内の特定のフォルダーを検索する方法が必要です。

パス「C:\ Program Files」にあるすべてのフォルダーのリストが必要です

以下は、上記のパスのフォルダー名です

  1. test123
  2. test4567
  3. フォルダー123
  4. フォルダー456
  5. フォルダー456 789

    リストで上記を取得してから、フォルダ456 789のみでフォルダ456のような特定の文字列を検索する必要があります。

コードの下で試してみました。私が下に欠けているもの:-

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\\")
27
che

簡単な方法で、lfsをインストールしてください。次に、次の構成を使用して必要なものを見つけます。

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

バックスラッシュが[[\]]に等しい"\\"に等しいこと、およびcmd自体で使用されていない場合はwindows /でも許可されていることに注意してください(これが間違っている場合は修正してください)。

25
jpjacobs

ライブラリ(特に、インストーラパッケージを使用してインストールすることを望んでいるライブラリ)をインストールする必要はありません。 Luaの絶対パスにあるディレクトリリストのクリーンなソリューションを探しているなら、もう探す必要はありません。

Sylvanaarが提供した答えに基づいて、特定のディレクトリのすべてのファイルの配列を返す関数を作成しました(絶対パスが必要です)。これは私のすべてのマシンで動作するため、私の好みの実装です。

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

Windowsを使用している場合、「ls」コマンドが機能するようにbashクライアントをインストールする必要があります-あるいは、sylvanaarが提供するdirコマンドを使用できます。

'dir "'..directory..'" /b /ad'
49
rhoster
 for dir in io.popen([[dir "C:\Program Files\" /b /ad]]):lines() do print(dir) end

* Windowsの場合

出力:

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

ループを通過するたびに、新しいフォルダー名が与えられます。例として印刷することにしました。

16
sylvanaar

ライブラリをインストールするのも好きではなく、PCよりもメモリの消費が少ない組み込みデバイスで作業しています。 「ls」コマンドを使用するとメモリ不足になることがわかりました。そこで、「find」を使用して問題を解決する関数を作成しました。

このようにして、メモリ使用量を一定に保ち、すべての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
13
Gert Oussoren

IIRC、ディレクトリリストの取得は、ストックLuaでは不可能です。グルーコードを自分で記述するか、 LuaFileSystem を使用する必要があります。後者は、おそらくあなたにとって最も抵抗の少ない道です。ドキュメントのクイックスキャンはlfs.dir()を示しています。これは、探しているディレクトリを取得するために使用できるイテレータを提供します。その時点で、文字列比較を実行して、必要な特定のディレクトリを取得できます。

2

また、「 paths 」モジュールをインストールして使用します。次に、次のように簡単にこれを行うことができます。

_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)
_

-これにより、すべてのフォルダー名が印刷されます

オプションで、fileName:find('$')fileName:find('txt' .. '$')に置き換えることにより、特定の拡張子を持つファイル名を探すこともできます

Unixベースのマシンで実行している場合、次のコードを使用して数値的にソートされたファイルのリストを取得できます。

_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
_

2番目のコードは、「。」などのファイルも除外しますおよび「..」。だから行くのは良いことです!

2
Amir

lsを解析しないでください、それは悪です!代わりにfindをゼロで終わる文字列とともに使用します(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

警告:ただし、ディレクトリ名に' 初期化。唯一の安全な解決策は、lfsまたは他の特別なライブラリを使用することです。

0
val