#bash #git #git-bash
#удар #мерзавец #гит-баш
Вопрос:
Мне нужно получить номер содержимого каталога, который является репозиторием git.
Мне нужно узнать номер:
1) Other directories inside the directory I am currently iterating (and the other sub-directories inside them if they exist) 2) .txt files inside the directory and its sub-directories 3) All the non-txt files inside the directory and its sub-directories
Во всех вышеперечисленных случаях я должен игнорировать каталог .git, а также все файлы и каталоги, которые находятся внутри него.
Кроме того, я должен использовать исключительно скрипт bash. Я не могу использовать другой язык программирования.
Прямо сейчас я использую следующие команды для достижения этой цели:
- Чтобы получить все
.txt
файлы, которые я использую :find . -type f ( -name "*.txt" )
. Внутри нет.txt
файлов.git
, так что это работает. - Чтобы получить все
non-txt
файлы, которые я использую:find . -type f ( ! -name "*.txt" )
. Проблема в том, что я также получаю все файлы.git
и не знаю, как их игнорировать. - Чтобы получить все
directories
иsub-directories
Я использую:find . -type d
. Я не знаю, как игнорировать.git
каталог и его подкаталоги
Ответ №1:
Самый простой способ — просто добавить эти дополнительные тесты:
find . ! -path './.git/*' ! -path ./.git -type f -name '*.txt'
Проблема в том, что это ./.git
все еще обходится без необходимости, что требует времени.
Вместо -prune
этого можно использовать. -prune
это не тест (например -path
, или -type
). Это действие. Действие «не спускайтесь по текущему пути, если это каталог». Он должен использоваться отдельно для действия печати.
# task 1 find . -path './.git' -prune -o -type f -name '*.txt' -print # task 2 find . -path './.git' -prune -o -type f ! -name '*.txt' -print # task 3 find . -path './.git' -prune -o -type d -print
- Если
-print
не указано,./.git
также печатается как действие по умолчанию. - Я использовал
-path ./.git
, потому что вы сказали «.git
каталог». Если по какой-то причине в дереве есть другие.git
каталоги, они будут пройдены и распечатаны. Чтобы игнорировать все каталоги в названном дереве.git
, замените-path ./.git
на-name .git
.
Комментарии:
1. Большое вам спасибо. Это работает идеально. Я просто хочу задать один вопрос. Когда я использую
find . -path './.git' -prune -o -type d -print
, я получаю.
каталог. Представляет ли это текущий каталог? Кроме того, как я могу игнорировать это в выводе?2. @SimosNeopoulos Да, я чуть было не упомянул об этом. Это текущий каталог, указанный с
find .
помощью . Этот префикс будет включен, если он совпадает. Это не совпадает в первых двух из-за-type f
. Вы можете сделать:find . -mindepth 1 -path './.git' -prune -o -type d -print
илиfind . -path './.git' -prune -o -type d ! -path . -print
.3. Лично я бы использовал
-name .git -prune
, так как Git не будет хранить ничего с именем.git
(по соображениям безопасности), и, следовательно, более простой-name
тест также соответствует тому, что делает Git. Но, конечно, и то, и другое работает.
Ответ №2:
Иногда написание цикла bash более понятно, чем однострочное
for f in $(find .); do if [[ -d $f amp;amp; "$f" == "./.git" ]]; then echo "skipping dir $f"; else echo "do something with $f"; fi; done
Комментарии:
1. Это не работает. Я запустил код, но все равно получаю все файлы и папки .git
2. вы должны изменить мой пример, чтобы он соответствовал вашим потребностям — там есть все необходимые компоненты …