分别在每个文件夹分支中查找第一个匹配项

分别在每个文件夹分支中查找第一个匹配项

给定以下文件夹布局:

Current_folder
└── FolderA
|   └── CMakeList.txt
|   └── FolderAA
|       └── CMakeList.txt
|
└── FolderB
|   └── FolderBA
|   |   └── CMakeList.txt
|   |   └── FolderBAA
|   |       └── CMakeList.txt
|   |
|   └── FolderBB
|       └── CMakeList.txt
|
└── FolderC
    └── CMakeList.txt
    └── FolderCA
        └── CMakeList.txt

我如何使用find(或任何其他工具)来产生类似于以下内容的输出:

Current_folder/FolderA/CMakeList.txt
Current_folder/FolderB/FolderBA/CMakeList.txt
Current_folder/FolderB/FolderBB/CMakeList.txt
Current_folder/FolderC/CMakeList.txt

这意味着在每个递归文件夹分支与文字“CMakeLists.txt”匹配后,搜索就会停止。

答案1

你可以做这样的事情:

for path in ./*;do find "$path" -type f -name "CMakeList.txt" -print -quit ;done
./FolderA/CMakeList.txt
./FolderB/FolderBB/CMakeList.txt
./FolderC/CMakeList.txt

这将打印文件的路径,并-quit尽快从每个文件中找到具有匹配名称的第一个文件小路喂养find "$path"

答案2

shell 函数(未经测试):

search () (
  if [ -f "$1"/CMakeList.txt ]
  then
    # if you get a file, print and stop recursing
    echo "${1%/}/CMakeList.txt"
    return
  fi
  for d in "$1"/*/
  do
    # nothing found in this directory, recurse to subdirectories
    search "${d%/}"
  done
)
search .

答案3

αғsнιη 的回答包含正确的解决方案find,但如果你有一个很多一个接一个地调用目录find可能会非常慢。如果你想利用所有的 CPU 核心并并行运行进程,find我建议GNUparallel对于任务:

parallel find {} -type f -regex "[^/]*/CMakeList.txt" -print -quit -o -regex "[^/]*/[^/]*/CMakeList.txt" -print ::: */

答案4

对我有用的是以下 bash 脚本:

#!/bin/bash
file_of_interest="CMakeList.txt"
latest_directory_wih_match=""

for current_directory in $(find -type d);
do
  if [[ (${latest_directory_wih_match} == "") || (! ${current_directory} == ${latest_directory_wih_match}*) ]];
  then
    if [ -f ${current_directory}/${file_of_interest} ]
    then
      latest_directory_wih_match=${current_directory}
      echo ${latest_directory_wih_match}/${file_of_interest}
    fi
  fi;
done

@dessert 的答案也适用于上述最小示例。将它用于我的实际文件夹结构(约 4000 个文件夹)时,它仍然给出错误的结果。老实说,我不确定为什么。

当我尝试@muru 的解决方案时,它不会停止执行。我猜是调用自身的函数没有正确中止?也不确定这里的原因。

PS:在实际的 CMake 项目中,该文件实际上名为“CMakeLists.txt”(请注意末尾的额外 s)。我只是在已经提供答案后才发现此错误。

相关内容