我想走一棵树,最后得到一个列表,其中每个目录最多包含一个文件。所选文件的唯一条件是它们与glob /模式匹配,例如“ *.txt
”。
如果还不是隐式的,我需要算法来返回稳定的结果。
例如给定一棵看起来像这样的树:
a/some/entry/foo.html
a/some/entry/foo.txt
a/some/entry/bar.txt
a/some/entry/baz.txt
a/some/entry/baz.bmp
a/some/boo.bat
a/some/boo.txt
a/some/bat.txt
a/other/path/far.txt
a/other/path/faz.txt
一个可以接受的结果是:
"a/some/entry/bar.txt a/other/path/far.txt a/some/boo.txt"
GLOB_RECURSE
和find_file
似乎不适合执行此任务,所以我应该考虑另一种方法吗?
答案 0 :(得分:1)
SET(resultfilelist "")
FILE(GLOB_RECURSE children LIST_DIRECTORIES true "${CMAKE_CURRENT_SOURCE_DIR}/a/*")
FOREACH(child ${children})
IF(IS_DIRECTORY ${child})
#message("Processing ${child}")
FILE(GLOB txtfiles LIST_DIRECTORIES false ${child}/*.txt)
list(LENGTH txtfiles txtfilessize)
IF(${txtfilessize} GREATER 0)
list(GET txtfiles 0 txtfilesfirst)
#message("Text file is ${txtfilesfirst}")
LIST(APPEND resultfilelist ${txtfilesfirst})
ENDIF()
ENDIF()
ENDFOREACH()
FOREACH(child ${resultfilelist})
message("Text file is ${child}")
ENDFOREACH()
答案 1 :(得分:1)
file (GLOB_RECURSE ...
返回的列表是所需结果的超集。因此,一种可能的解决方案是仅选择每个目录返回的第一个匹配项来对返回的列表进行后期处理。
以下CMake函数概述了必要的步骤:
function (glob_recurse_first _globbingExpression _resultVar)
file (GLOB_RECURSE _pathList "${_globbingExpression}")
# canonical order
list (SORT _pathList)
# filter first match from each directory
set (_firstMatched "")
set (_latestDir "//")
foreach (_path IN LISTS _pathList)
get_filename_component(_dir "${_path}" DIRECTORY)
if (NOT "${_dir}" STREQUAL "${_latestDir}")
list (APPEND _firstMatched "${_path}")
set (_latestDir "${_dir}")
endif()
endforeach()
set (${_resultVar} ${_firstMatched} PARENT_SCOPE)
endfunction()
该功能可以通过以下方式使用:
glob_recurse_first("a/*.txt" _fileList)
foreach (_file ${_fileList})
message (STATUS "${_file}")
endforeach()
遍历表达式"a/*.txt"
将保留目录.txt
中带有扩展名a
的所有文件及其所有子目录。
结果变量_fileList
包含绝对路径,a
中每个子目录都有一个文件。
答案 2 :(得分:1)
我不确定,但是您可以创建一个可执行文件来通过命令搜索目录
$ grep -R version | awk -F: '/CMake.*:/ {print $1}'
像这个例子
https://unix.stackexchange.com/a/105342
,您可以将结果保存到新文件中,如果需要进一步开发,可以包含此文件