Учитывая следующий макет папки:
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» для каждой рекурсивной ветви папок соответственно.
, что работал для меня было следующие bash-скрипт:
[Ф1]ответы@десерт работали за минимальный пример выше. Используя его на мою реальную структуру папок (~папок 4000), все равно было давать неверные результаты. Я не знаю, почему, честно говоря.
, когда я попробовал решение @Муру это не останавливает выполнение. Я предполагаю, что функции, называющая себя не прерываясь? Не уверен, что причина здесь.
ЗЫ: в случае с cmake проекта файл на самом деле называется "CMakeLists.txt" (обратите внимание на дополнительную s в конце). Я заметил эту ошибку только после того, как ответы уже давались.
Для меня работал следующий скрипт 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 в конце). Я заметил эту ошибку только после того, как ответы уже были предоставлены.
Для меня работал следующий скрипт 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 в конце). Я заметил эту ошибку только после того, как ответы уже были предоставлены.
Вы могли бы сделать что-то вроде этого:
[Ф1]это выведет путь к файлу и [Ф2], как только первый файл с нашли подходящих имен из каждого путь, подавая в [Ф3].
Функция оболочки (непроверенная):
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 .
ответ αғsнιη содержит правильные решения с [Ф2], но если у вас много каталогов, позвонив по одному [Ф3] после другой может быть довольно медленным. Если вы хотите использовать все ядра процессора и запустить [F4] для процессов параллельно я рекомендую ГНУ [ф5] задачи:
[Ф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". [ ! d1]
Вы сделали бы что-то вроде этого:
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". [ ! d1]