Как может я добираться 'найти' для игнорирования .svn каталогов?

Я часто использую find команда для поиска исходного кода удалите файлы, безотносительно. Раздражающе, потому что Подверсия хранит дубликаты каждого файла в .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, это больше не проблема.

Основной характеристикой изменений, представленных в Подверсии 1.7, является централизация рабочего устройства хранения данных метаданных копии в единственное местоположение. Вместо a .svn каталог в каждом каталоге в рабочей копии, Подверсия 1,7 рабочих копии имеют всего один .svn каталог — в корне рабочей копии. Этот каталог включает (среди прочего) SQLite-поддержанную базу данных, которая содержит все потребности Подверсии метаданных в той рабочей копии.

221
задан John Kugelman supports Monica 22 January 2015 в 05:28
поделиться

11 ответов

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

65
ответ дан 23 November 2019 в 04:02
поделиться

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

findrepo uint 'messages.*'
2
ответ дан 23 November 2019 в 04:02
поделиться

GNU find

find .  ! -regex ".*[/]\.svn[/]?.*"
12
ответ дан 23 November 2019 в 04:02
поделиться

Как указано ниже:

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

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

find . -name .svn -a -type d -prune -o -print
140
ответ дан 23 November 2019 в 04:02
поделиться

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

your find command| grep -v '\.svn'
7
ответ дан 23 November 2019 в 04:02
поделиться

Создайте сценарий под названием ~ / 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;
8
ответ дан 23 November 2019 в 04:02
поделиться

находка. | grep -v \ .svn

8
ответ дан 23 November 2019 в 04:02
поделиться

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

2
ответ дан 23 November 2019 в 04:02
поделиться

Я использую для этой цели 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 автоматически использует эти параметры при вызове

10
ответ дан 23 November 2019 в 04:02
поделиться

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

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

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

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

    Находка | grep | xargs подход похож на GNU find параметр -regex (см. сообщение ghostdog74 ), но более переносимый (также будет работать на платформы, на которых GNU find недоступен.)

5
ответ дан 23 November 2019 в 04:02
поделиться

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

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

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

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

find -not -iwholename '*.svn*' -name 'messages.*' -exec grep -Iw uint {} + \;
289
ответ дан 23 November 2019 в 04:02
поделиться
Другие вопросы по тегам:

Похожие вопросы: