我目前正在阅读《Real World Haskell》一书,该书中的一个练习要求读者使用来实现文件名匹配,该用法**
与相同*
,但在文件系统的所有子目录中也进行查找。下面是我的代码片段,带注释(此刻有很多重复),进一步,您可以找到有关该代码的其他信息。我认为发布的代码足以解决问题,因此无需在此处列出整个程序。
case splitFileName pat of
("", baseName) -> do -- just the file name passed
curDir <- getCurrentDirectory
if searchSubDirs baseName -- check if file name has `**` in it
then do
contents <- getDirectoryContents curDir
subDirs <- filterM doesDirectoryExist contents
let properSubDirs = filter (`notElem` [".", ".."]) subDirs
subDirsNames <- forM properSubDirs $ \dir -> do
namesMatching (curDir </> dir </> baseName) -- call the function recursively on subdirectories
curDirNames <- listMatches curDir baseName -- list matches in the current directory
return (curDirNames ++ (concat subDirsNames)) -- concatenate results into a single list
else listMatches curDir baseName
(dirName, baseName) -> do // full path passed
if searchSubDirs baseName
then do
contents <- getDirectoryContents dirName
subDirs <- filterM doesDirectoryExist contents
let properSubDirs = filter (`notElem` [".", ".."]) subDirs
subDirsNames <- forM properSubDirs $ \dir -> do
namesMatching (dirName </> dir </> baseName) -- call the function recursively on subdirectories
curDirNames <- listMatches dirName baseName -- list matches in the passed directory
return (curDirNames ++ (concat subDirsNames)) -- concatenate results into a single list
pat
是我正在寻找的模式(例如*.txt
或C:\\A\[a-z].*
)。
splitFileName
是将文件路径分为目录路径和文件名的功能。如果我们仅在中指定文件名,则元组的第一个元素将为空pat
。
searchSubDirs
返回True
文件名是否包含**
在其中。
listMatches
返回目录匹配模式的,用文件名列表**
的*
。
namesMatching
是我发布其摘录的函数的名称。
当我仅传递文件名时,程序仅在当前目录和第一级子目录中搜索它。当我传递完整路径时,它仅在指定目录中搜索。看来大小写(dirName, baseName)
没有正确递归。我已经看了一段时间的代码了,但我不知道问题出在哪里。
如果需要更多信息,请在评论中让我知道,我将在问题中添加所有必要内容。
这是一个问题:
contents <- getDirectoryContents dirName
subDirs <- filterM doesDirectoryExist contents
getDirectoryContents
仅返回目录的叶名称,因此您必须在之前在元素之前加上dirName
(以及/
)。contents
doesDirectoryExist
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句