Как я могу заставить `find` игнорировать каталоги .svn?

227

Я часто использую findкоманду для поиска по исходному коду, удаления файлов, чего угодно. Досадно, потому что Subversion хранит дубликаты каждого файла в своих .svn/text-base/каталогах, мои простые поиски заканчиваются тем, что они получают много повторяющихся результатов. Например, я хочу , чтобы рекурсивно искать uintв многократном messages.hи messages.cppфайлов:

# find -name 'messages.*' -exec grep -Iw uint {} +
./messages.cpp:            Log::verbose << "Discarding out of date message: id " << uint(olderMessage.id)
./messages.cpp:    Log::verbose << "Added to send queue: " << *message << ": id " << uint(preparedMessage->id)
./messages.cpp:                Log::error << "Received message with invalid SHA-1 hash: id " << uint(incomingMessage.id)
./messages.cpp:            Log::verbose << "Received " << *message << ": id " << uint(incomingMessage.id)
./messages.cpp:            Log::verbose << "Sent message: id " << uint(preparedMessage->id)
./messages.cpp:        Log::verbose << "Discarding unsent message: id " << uint(preparedMessage->id)
./messages.cpp:        for (uint i = 0; i < 10 && !_stopThreads; ++i) {
./.svn/text-base/messages.cpp.svn-base:            Log::verbose << "Discarding out of date message: id " << uint(olderMessage.id)
./.svn/text-base/messages.cpp.svn-base:    Log::verbose << "Added to send queue: " << *message << ": id " << uint(preparedMessage->id)
./.svn/text-base/messages.cpp.svn-base:                Log::error << "Received message with invalid SHA-1 hash: id " << uint(incomingMessage.id)
./.svn/text-base/messages.cpp.svn-base:            Log::verbose << "Received " << *message << ": id " << uint(incomingMessage.id)
./.svn/text-base/messages.cpp.svn-base:            Log::verbose << "Sent message: id " << uint(preparedMessage->id)
./.svn/text-base/messages.cpp.svn-base:        Log::verbose << "Discarding unsent message: id " << uint(preparedMessage->id)
./.svn/text-base/messages.cpp.svn-base:        for (uint i = 0; i < 10 && !_stopThreads; ++i) {
./virus/messages.cpp:void VsMessageProcessor::_progress(const string &fileName, uint scanCount)
./virus/messages.cpp:ProgressMessage::ProgressMessage(const string &fileName, uint scanCount)
./virus/messages.h:    void _progress(const std::string &fileName, uint scanCount);
./virus/messages.h:    ProgressMessage(const std::string &fileName, uint scanCount);
./virus/messages.h:    uint        _scanCount;
./virus/.svn/text-base/messages.cpp.svn-base:void VsMessageProcessor::_progress(const string &fileName, uint scanCount)
./virus/.svn/text-base/messages.cpp.svn-base:ProgressMessage::ProgressMessage(const string &fileName, uint scanCount)
./virus/.svn/text-base/messages.h.svn-base:    void _progress(const std::string &fileName, uint scanCount);
./virus/.svn/text-base/messages.h.svn-base:    ProgressMessage(const std::string &fileName, uint scanCount);
./virus/.svn/text-base/messages.h.svn-base:    uint        _scanCount;

Как я могу сказать, findчтобы игнорировать .svnкаталоги?


Обновление : если вы обновляете свой клиент SVN до версии 1.7, это больше не проблема.

Ключевой особенностью изменений, внесенных в Subversion 1.7, является централизация хранилища метаданных рабочей копии в одном месте. Вместо .svnкаталога в каждом каталоге в рабочей копии рабочие копии Subversion 1.7 имеют только один .svnкаталог - в корне рабочей копии. Этот каталог включает (среди прочего) базу данных на основе SQLite, которая содержит все метаданные, необходимые Subversion для этой рабочей копии.

Джон Кугельман
источник
4
Для производительности попробуйте использовать find ... -print0 | xargs -0 egrep ...вместо find ... -exec grep ...(не grepдля каждого файла, но для нескольких файлов одновременно). С помощью этой формы вы также можете обрезать .svnкаталоги, не используя -pruneопцию find, т.е.find ... -print0 | egrep -v '/\.svn' | xargs -0 egrep ...
vladr
3
@Vlad: Насколько я знаю, использование -execwith +не разветвляется grepдля каждого файла, в то время как использование with ;делает. Использование -execна самом деле более правильно, чем использование xargs. Обратите внимание, что такие команды как lsчто-то делают, даже если список аргументов пуст, в то время как такие команды chmodдают ошибку, если аргументов недостаточно. Для того, чтобы увидеть , что я имею в виду, просто попробуйте следующую команду в каталоге , который не имеет какой - либо скрипт: find /path/to/dir -name '*.sh' -print0 | xargs -0 chmod 755. Сравните с этим: find /path/to/dir -name '*.sh' -exec chmod 755 '{}' '+'.
Сиу Чинг Понг - Асука Кэндзи -
2
@Vlad: Кроме того, grepвыход .svnтоже не очень хорошая идея. Пока findспециализируется на обработке свойств файла, grepнет. В вашем примере файл с именем '.svn.txt' также будет отфильтрован вашей egrepкомандой. Хотя вы можете изменить свое регулярное выражение на «^ / \. Svn $» , это все же не очень хорошая практика. -pruneПредикат findотлично работает для фильтрации файлов (по имени файла, или создания временной метки, или независимо от состояния вы прилагается). Это похоже на то, что даже если вы можете убить таракана с помощью большого меча, это не значит, что это рекомендуемый способ сделать это :-).
Сиу Чинг Понг-Асука Кэндзи -
3
Переход на Git исправил эту проблему (среди многих других). In создает только папку .git в корне рабочей копии, а не в каждой папке, такой как SVN. Кроме того, папка .git не содержит простых файлов, которые могут быть перепутаны с вашими фактическими файлами с такими же именами.
Tronic
3
2Dan Molding: svn 1.7 создает только один каталог верхнего уровня .svn
ccpizza

Ответы:

65

Для поиска могу я предложить вам посмотреть на ack ? Он осведомлен об исходном коде findи поэтому автоматически игнорирует многие типы файлов, включая информацию о репозитории исходного кода, такую ​​как приведенная выше.

Брайан Агнью
источник
3
Мне ackочень нравится , но я обнаружил, что это значительно медленнее, чем find -type f -name "*.[ch]" | xargs grepпри работе с большой кодовой базой.
Джон Ледбеттер
63
Джон, я автор ack, и если вы можете дать мне подробную информацию о проблемах скорости ack против grep, я был бы признателен. Они были полностью сопоставимы во всех случаях, которые я нашел. Либо дайте мне знать по адресу github.com/petdance/ack/issues, либо напишите мне по адресу Энди на petdance.com. Thansk.
Энди Лестер
63
Ребята, это совет, но определенно не ответ на вопрос! :)
dolzenko
8
Разве не ackсчитается, что лучше grep, не с учетом источника find? Некоторые примеры использования его для замены findсделают это реальным ответом.
michiakig
3
Это ответ на вопрос, который он не знал, он задавал. =)
Фрунги
293

почему не просто

find . -not -iwholename '*.svn*'

Предикат -not отменяет все, что имеет .svn в любом месте пути.

Так что в вашем случае это будет

find -not -iwholename '*.svn*' -name 'messages.*' -exec grep -Iw uint {} + \;
Уэйли
источник
5
Супер большой +1 для "-not" и "-iwholename". Ack - это замечательно, и я им пользуюсь, но find / exec все еще находит применение.
Дэвид Блевинс
9
Единственный ответ, который фактически ответил на оригинальный вопрос.
Брендон Кроуфорд
14
Я далеко от своего элемента и уверен, что меня будут критиковать за этот комментарий, но, очевидно, -not и -wholename не POSIX-совместимые. Я использовал ! вместо-not и -path вместо -iwholename и получили те же результаты. Согласно моим справочным страницам (Ubuntu 12.04) этот синтаксис является POSIX-совместимым.
Джон
1
@whaley Ты сказал '*.svn*'сначала, но потом '*.svn'. Какой правильный? Работают ли оба? Я думаю, что это должно быть '*.svn*'?
Кит М
1
@KeithM отличный улов на самом деле. Этот ответ сидел здесь годами, и я не думаю, что кто-то поймал это до сих пор.
Кит
141

Следующим образом:

find . -path '*/.svn*' -prune -o -print

Или, альтернативно, на основе каталога, а не префикса пути:

find . -name .svn -a -type d -prune -o -print
Калеб Педерсон
источник
14
@ Калеб: Привет. Я предлагаю, find . -type d -name .svn -prune -o -printпотому что это немного быстрее. Согласно стандарту POSIX , выражения оцениваются одно за другим в указанном порядке. Если первое выражение в -aявляется false, второе выражение не будет оценено (также называемое коротким замыканием и оценкой ).
Сиу Чинг Понг-Асука Кэндзи -
2
@ Kaleb: поскольку сравнение типа файла (эквивалентно проверке, установлен ли бит в целом числе) быстрее, чем сравнение имени файла (эквивалент сравнения строк, который равен O (n)), установка -type dперед -name .svnтеоретически более эффективна. Тем не менее, это обычно незначительно, за исключением случаев, когда у вас очень очень большое дерево каталогов.
Сиу Чинг Понг-Асука Кэндзи -
5
@ SiuChingPong-AsukaKenji - нет, сравнение только имени файла происходит быстрее, потому что -type требует вызова stat (2) для каждого файла. Имя файла, однако, является частью ответа readdir (3).
Храбан
3
@JonathanHartley Вы пропустите -printкак часть последнего выражения. Нечто подобное find . -name .git -prune -o \( -type f -name LICENSE -print \)работает как положено.
Щуберт
1
Если вы хотите игнорировать как .git и .svn и просто перечислить другие каталоги, find . -name .svn -prune -o -name .git -prune -o -type d -print. Это может быть на несколько миллисекунд быстрее, -type dчем раньше -name, но это не стоит дополнительного набора текста.
JPaget
34

Для того, чтобы игнорировать .svn, .gitи другие скрытые каталоги (начинающиеся с точки), попробуйте:

find . -type f -not -path '*/\.*'

Однако, если целью использования findявляется поиск в файлах, вы можете попробовать использовать эти команды:

  • git grep - специально разработанная команда для поиска шаблонов в репозитории Git.
  • ripgrep- который по умолчанию игнорирует скрытые файлы и файлы, указанные в .gitignore.

Связанный: Как мне найти все файлы, содержащие определенный текст в Linux?

kenorb
источник
Лучший ответ IMO. Другие пытаются объяснить вещи, которые не отвечают на простой вопрос.
Энтони
19

Вот что я бы сделал в вашем случае:

find . -path .svn -prune -o -name messages.* -exec grep -Iw uint {} +

rgrepВстроенная команда Emacs игнорирует .svnкаталог и многие другие файлы, которые вам, вероятно, не нужны при выполнении find | grep. Вот что он использует по умолчанию:

find . \( -path \*/SCCS -o -path \*/RCS -o -path \*/CVS -o -path \*/MCVS \
          -o -path \*/.svn -o -path \*/.git -o -path \*/.hg -o -path \*/.bzr \
          -o -path \*/_MTN -o -path \*/_darcs -o -path \*/\{arch\} \) \
     -prune -o \
       \( -name .\#\* -o -name \*.o -o -name \*\~ -o -name \*.bin -o -name \*.lbin \
          -o -name \*.so -o -name \*.a -o -name \*.ln -o -name \*.blg \
          -o -name \*.bbl -o -name \*.elc -o -name \*.lof -o -name \*.glo \
          -o -name \*.idx -o -name \*.lot -o -name \*.fmt -o -name \*.tfm \
          -o -name \*.class -o -name \*.fas -o -name \*.lib -o -name \*.mem \
          -o -name \*.x86f -o -name \*.sparcf -o -name \*.fasl -o -name \*.ufsl \
          -o -name \*.fsl -o -name \*.dxl -o -name \*.pfsl -o -name \*.dfsl \
          -o -name \*.p64fsl -o -name \*.d64fsl -o -name \*.dx64fsl -o -name \*.lo \
          -o -name \*.la -o -name \*.gmo -o -name \*.mo -o -name \*.toc \
          -o -name \*.aux -o -name \*.cp -o -name \*.fn -o -name \*.ky \
          -o -name \*.pg -o -name \*.tp -o -name \*.vr -o -name \*.cps \
          -o -name \*.fns -o -name \*.kys -o -name \*.pgs -o -name \*.tps \
          -o -name \*.vrs -o -name \*.pyc -o -name \*.pyo \) \
     -prune -o \
     -type f \( -name pattern \) -print0 \
     | xargs -0 -e grep -i -nH -e regex

Он игнорирует каталоги, созданные большинством систем контроля версий, а также созданные файлы для многих языков программирования. Вы можете создать псевдоним , который вызывает эту команду и заменить findи grepшаблоны для ваших проблем конкретных.

Antoine
источник
12

GNU найти

find .  ! -regex ".*[/]\.svn[/]?.*"
ghostdog74
источник
Я загружал пути к каталогам в массив для обработки PHP. Другие ответы выше (по какой-либо причине) не отфильтровали файлы в поиске (несмотря на -type d) - этот ответ сделал. +1
будь холленбеком
11

Я использую grep для этой цели. Поместите это в ваш ~ / .bashrc

export GREP_OPTIONS="--binary-files=without-match --color=auto --devices=skip --exclude-dir=CVS --exclude-dir=.libs --exclude-dir=.deps --exclude-dir=.svn"

grep автоматически использует эти опции при вызове

Ронни Брендель
источник
1
Стоит отметить, что «grep» получил опцию «--exclude-dir» только год или два назад. Последние дистрибутивы Linux включают его, но, если я правильно помню, мне пришлось скомпилировать свой собственный grep (или попросить сделать это у homebrew) в OSX.
Джонатан Хартли
Я использую второстепенный вариант этого. Мой .bashrc создает функцию Bash 'grp', которая определяется как GREP_OPTIONS=xxx grep "$@". Это означает, что переменная GREP_OPTIONS установлена ​​только для экземпляров grep, которые я запускаю вручную, используя 'grp'. Это означает, что у меня никогда не возникает ситуация, когда я запускаю инструмент, и внутренне он вызывает grep, но инструмент запутывается, потому что grep ведет себя не так, как ожидалось. Кроме того, у меня есть вторая функция grpy, которая вызывает grp, но добавляет --include=*.py, чтобы просто искать файлы Python.
Джонатан Хартли
На самом деле, если подумать, для этого больше не нужно использовать GREP_OPTIONS. Теперь у меня есть только функция оболочки 'grp', которая вызывает grep --exclude=tags --exclude_dir=.git ...etc... "$@". Мне нравится, что это работает как «ack», но я сохраняю понимание и контроль над тем, что он делает.
Джонатан Хартли
9

find . | grep -v \.svn

меня.
источник
Вы должны сбежать .в .svnрегулярном выражении.
влад
4
Используйте --fixed-strings с grep: | fgrep -v /.svn/или `| grep -F -v / .svn / `для исключения именно каталога, а не файлов с" .svn "как частью их имени.
Стивен П.
8

Почему бы вам не передать команду с помощью grep, который легко понять:

your find command| grep -v '\.svn'
Виджай
источник
Вы должны сбежать .в .svnрегулярном выражении.
влад
@Yclian без тени сомнения; если вы этого не сделаете, каталоги с именами 'tsvn', '1svn', 'asvn' и т. д. также будут игнорироваться, поскольку '.' является подстановочным знаком регулярного выражения: 'соответствовать любому символу'.
влад
Хорошо, я думал, что это произойдет только в случае -E и -G. Я только что проверил, мой плохой. :(
yclian
2
Мне нравится этот ответ, потому что он концептуально проще, чем все остальные. Я не могу вспомнить смешной синтаксис для использования 'find', но я точно могу вспомнить, как использовать grep -v, поскольку он используется во многих ситуациях.
mattismyname
8

Создайте скрипт с именем ~/bin/svnfind:

#!/bin/bash
#
# Attempts to behave identically to a plain `find' command while ignoring .svn/
# directories.

OPTIONS=()
PATHS=()
EXPR=()

while [[ $1 =~ ^-[HLP]+ ]]; do
    OPTIONS+=("$1")
    shift
done

while [[ $# -gt 0 ]] && ! [[ $1 =~ '^[-(),!]' ]]; do
    PATHS+=("$1")
    shift
done

# If user's expression contains no action then we'll add the normally-implied
# `-print'.
ACTION=-print

while [[ $# -gt 0 ]]; do
    case "$1" in
       -delete|-exec|-execdir|-fls|-fprint|-fprint0|-fprintf|-ok|-print|-okdir|-print0|-printf|-prune|-quit|-ls)
            ACTION=;;
    esac

    EXPR+=("$1")
    shift
done

if [[ ${#EXPR} -eq 0 ]]; then
    EXPR=(-true)
fi

exec -a "$(basename "$0")" find "${OPTIONS[@]}" "${PATHS[@]}" -name .svn -type d -prune -o '(' "${EXPR[@]}" ')' $ACTION

Этот скрипт ведет себя идентично простой findкоманде, но он удаляет .svnкаталоги. В остальном поведение идентично.

Пример:

# svnfind -name 'messages.*' -exec grep -Iw uint {} +
./messages.cpp:            Log::verbose << "Discarding out of date message: id " << uint(olderMessage.id)
./messages.cpp:    Log::verbose << "Added to send queue: " << *message << ": id " << uint(preparedMessage->id)
./messages.cpp:                Log::error << "Received message with invalid SHA-1 hash: id " << uint(incomingMessage.id)
./messages.cpp:            Log::verbose << "Received " << *message << ": id " << uint(incomingMessage.id)
./messages.cpp:            Log::verbose << "Sent message: id " << uint(preparedMessage->id)
./messages.cpp:        Log::verbose << "Discarding unsent message: id " << uint(preparedMessage->id)
./messages.cpp:        for (uint i = 0; i < 10 && !_stopThreads; ++i) {
./virus/messages.cpp:void VsMessageProcessor::_progress(const string &fileName, uint scanCount)
./virus/messages.cpp:ProgressMessage::ProgressMessage(const string &fileName, uint scanCount)
./virus/messages.h:    void _progress(const std::string &fileName, uint scanCount);
./virus/messages.h:    ProgressMessage(const std::string &fileName, uint scanCount);
./virus/messages.h:    uint        _scanCount;
оборота Джон Кугельман
источник
Этот скрипт не работает, как я ожидал. При запуске с "svnfind -type f", он также печатает svn-каталоги и файлы в svn-каталогах
Ingo Fischer
@ifischer Можете ли вы добавить команду echoк команде find и сказать, какая команда выполняется? svnfind -type fотлично работает на моей машине Red Hat.
Джон Кугельман
Итак, похоже, это зависит от ОС. Я использую Debian Squeeze (то же самое в Ubuntu). Я не понимаю, что вы подразумеваете под "добавить эхо"?
Инго Фишер
@ifischer Измените последнюю строку на echo find "${OPTIONS[@]}"...так, чтобы она печатала команду поиска вместо фактического ее запуска.
Джон Кугельман
ОК изменил последнюю строку на echo find ${OPTIONS[@]} ${PATHS[@]} -name .svn -type d -prune -o ( ${EXPR[@]} ) $ACTION, Это дает мне следующий вывод:find -type f -name .svn -type d -prune -o ( -true ) -print
Инго Фишер
5

Просто подумал, что я добавлю простую альтернативу постам Калеба и других (которые подробно описывают использование find -pruneопции ack, repofindкоманд и т. Д.), Которая особенно применима к использованию, которое вы описали в вопросе (и любым другим подобным использованиям):

  1. Для повышения производительности, вы всегда должны пытаться использовать find ... -exec grep ... +(спасибо Кэндзи за указание на это) или find ... | xargs egrep ...(переносной) или find ... -print0 | xargs -0 egrep ...(GNU; работы на имена файлов , содержащих пробелы) , а не из find ... -exec grep ... \;.

    Форма find ... -exec ... +and find | xargsне форкается egrepдля каждого файла, а скорее для нескольких файлов за раз, что приводит к гораздо более быстрому выполнению .

  2. При использовании find | xargsформы также можно использовать , grepчтобы легко и быстро чернослив .svn(или любые каталоги или регулярное выражение), то есть find ... -print0 | grep -v '/\.svn' | xargs -0 egrep ...(полезно , когда вам нужно что - то быстро и не могут быть обеспокоены , чтобы помнить , как настроить find«s -pruneлогику.)

    find | grep | xargsПодход аналогичен GNU find«S -regexопции (см ghostdog74» s пост), но более компактен (также будет работать на платформах , где GNU findне доступен.)

vladr
источник
1
@Vlad: Обратите внимание, что для -execпереключения есть две формы find: одна заканчивается ;на другую, а другая заканчивается на +. Один, заканчивающийся на, +заменяет {}список всех соответствующих файлов. Кроме того, ваше регулярное выражение также '/\.svn'соответствует именам файлов '.svn.txt'. Пожалуйста, обратитесь к моим комментариям к вопросу для получения дополнительной информации.
Сиу Чинг Понг-Асука Кэндзи -
2
@Vlad: вот стандарт POSIX для этой findутилиты. Пожалуйста, смотрите -execчасть :-).
Сиу Чинг Понг-Асука Кэндзи -
4

В репозитории исходного кода я обычно хочу делать вещи только с текстовыми файлами.

Первая строка - это все файлы, кроме файлов репозитория CVS, SVN и GIT.

Вторая строка исключает все двоичные файлы.

find . -not \( -name .svn -prune -o -name .git -prune -o -name CVS -prune \) -type f -print0 | \
xargs -0 file -n | grep -v binary | cut -d ":" -f1
rickfoosusa
источник
3

Я использую find с опциями -not -path. Мне не повезло с черносливом.

find .  -name "*.groovy" -not -path "./target/*" -print

найдет файлы groovy не в пути к целевому каталогу.

Скотт М Гарднер
источник
3

Чтобы решить эту проблему, вы можете просто использовать это условие поиска:

find \( -name 'messages.*' ! -path "*/.svn/*" \) -exec grep -Iw uint {} +

Вы можете добавить больше ограничений следующим образом:

find \( -name 'messages.*' ! -path "*/.svn/*" ! -path "*/CVS/*" \) -exec grep -Iw uint {} +

Вы можете найти более подробную информацию об этом в справочной странице раздела «Операторы»: http://unixhelp.ed.ac.uk/CGI/man-cgi?find

Код-Source
источник
3

Обратите внимание, что если вы делаете

find . -type f -name 'messages.*'

тогда -printподразумевается, когда все выражение ( -type f -name 'messages.*') истинно, потому что нет «действия» (например -exec).

Хотя, чтобы прекратить спуск в определенные каталоги, вы должны использовать все, что соответствует этим каталогам, и следовать за ним -prune(что предназначено для того, чтобы прекратить спуск в каталоги); вот так:

find . -type d -name '.svn' -prune

Это дает значение True для каталогов .svn, и мы можем использовать логическое короткое замыкание, следуя за этим -o(OR), после чего то, что следует после, -oпроверяется только тогда, когда первая часть имеет значение False, следовательно, не является каталогом .svn. Другими словами, следующее:

find . -type d -name '.svn' -prune -o -name 'message.*' -exec grep -Iw uint {}

будет только оценивать то, что правильно -o, а именно -name 'message.*' -exec grep -Iw uint {}, для файлов НЕ внутри .svn каталогов.

Обратите внимание, что, поскольку .svn, скорее всего, это всегда каталог (а не, например, файл), и в этом случае, конечно, он не совпадает с именем «message. *», Вы можете также пропустить -type dи сделать:

find . -name '.svn' -prune -o -name 'message.*' -exec grep -Iw uint {}

Наконец, обратите внимание, что если вы пропустите какое-либо действие ( -execэто действие), скажите примерно так:

find . -name '.svn' -prune -o -name 'message.*'

тогда -printдействие подразумевается, но будет применяться к выражению -name '.svn' -prune -oWHOLE , включая часть, и, таким образом, печатать все каталоги .svn, а также файлы 'message. *', что, вероятно, не то, что вам нужно. Поэтому при использовании -pruneтаким способом вы всегда должны использовать «действие» в правой части логического выражения . И когда это действие печатается, вы должны явно добавить его, например, так:

find . -name '.svn' -prune -o -name 'message.*' -print

Карло Вуд
источник
2

Попробуйте findrepo, который является простой оболочкой для find / grep и намного быстрее, чем ack. В этом случае вы бы использовали его следующим образом:

findrepo uint 'messages.*'
pixelbeat
источник
2

wcfind скрипт поиска оболочки, который я использую для автоматического удаления каталогов .svn

leedm777
источник
1

Это работает для меня в приглашении Unix

гфинд \ (-not -wholename '* \. svn *' \) -type f -name 'messages. *' -exec grep -Iw uint {} +

Приведенная выше команда выведет список файлов, которые не относятся к .svn, и выполнит упомянутый вами grep.

Феликс
источник
«gfind» - опечатка? У меня его нет в Ubuntu 14.04.
Джонатан Хартли,
Предполагая, что вы имели в виду «найти», это не совсем работает. Это также отфильтровывает файлы как xxx.svnxxx. Это важно - например, если вы используете git вместо svn, вам часто нужно включать файлы, такие как .gitignore (это не метаданные, это обычный файл, который включен в репозиторий) в результаты поиска.
Джонатан Хартли
1

я обычно передаю вывод через grep еще раз, удаляя .svn, в моем случае он не намного медленнее. Типичный пример:

find -name 'messages.*' -exec grep -Iw uint {} + | grep -Ev '.svn|.git|.anythingElseIwannaIgnore'

ИЛИ

find . -type f -print0 | xargs -0 egrep messages. | grep -Ev '.svn|.git|.anythingElseIwannaIgnore'
geminiimatt
источник
0

Если вы скажете find для поиска через '*', тогда он пропустит все "точечные файлы" в корне:

find *

или с пути

find /path/*

Это не точное / идеальное решение вопроса. Однако немногие решения проще, чем это. Производительность тоже отличная, поскольку она даже не входит в скрытые каталоги.

недостатки:

  • он не обрабатывает вложенные «точечные файлы».
  • все "точечные файлы" игнорируются, а не только ".git" и ".svn".

Таким образом, в вашем примере добавление звезды - единственная модификация, которая вам понадобится:

find * -name 'messages.*' -exec grep -Iw uint {} +
Эрик Лиеваарт
источник