Как удалить все каталоги .svn из моих каталогов приложений

193

Одна из задач инструмента экспорта, который есть в моем приложении, - очистить все .svnкаталоги от дерева каталогов моего приложения. Я ищу рекурсивную команду в оболочке Linux, которая будет проходить по всему дереву и удалять .svnфайлы.

Я не использую экспорт, так как этот скрипт будет использоваться для некоторых других имен файлов / каталогов, которые не связаны с SVN. Я попробовал что-то вроде:

find . -name .svn | rm -fr

Это не сработало ...

Итай Моав -Малимовка
источник
3
Ваша команда должна работать, если вы используете 'xargs rm -rf'
Питер ван дер Хейден
1
Вы также можете изменить команду удаления "rm -rfi", чтобы убедиться, что вы уверены, что хотите удалить каталоги.
ночевка
Не используйте xargs, хотя ... у вас будут проблемы с каталогами, в которых есть пробелы и т. Д. Используйте find, как описано ниже.
Джон Хант

Ответы:

439

Попробуй это:

find . -name .svn -exec rm -rf '{}' \;

Перед тем, как запустить такую ​​команду, я часто хотел бы сначала выполнить это:

find . -name .svn -exec ls '{}' \;
Greg
источник
43
Возможно, вам придется поместить {} в одинарные кавычки, если в каталогах может быть пробел или такие символы: find . -name .svn -exec rm -rf '{}' \;
mtoloo
38
Этот тест лучше работает в моем bash:find . -name .svn -exec echo {} \;
Fedir RYKHTIK
6
Первый запуск echo / ls - это «профессиональный» штрих к этому ответу. Любой дурак может разрушить систему.
Джон Хант
6
что делает {} \;?
Джон Миттен
3
lsentries prop-base props text-base tmp
Запустив
51

То, что вы написали, отправляет список имен файлов (и путей) rm, разделенных символом новой строки , но rm не знает, что делать с этим вводом. Ожидаются только параметры командной строки.

xargs принимает входные данные, обычно разделенные символами новой строки, и помещает их в командную строку, поэтому добавление xargs делает то, что у вас было:

find . -name .svn | xargs rm -fr

xargsдостаточно умен, чтобы передать столько аргументов, rmсколько может принять. Таким образом, если у вас есть миллион файлов, он может выполняться rm1 000 000/65 000 раз (если ваша оболочка может принять 65 002 аргумента в командной строке {65k файлов + 1 для rm + 1 для -fr}).

Как умело указали люди, также работают следующие:

find . -name .svn -exec rm -rf {} \;
find . -depth -name .svn -exec rm -fr {} \;
find . -type d -name .svn -print0|xargs -0 rm -rf

Первые две -execформы вызывают rmкаждую удаляемую папку, поэтому, если у вас есть 1 000 000 папок, rmони будут вызваны 1 000 000 раз. Это конечно не идеально. Более новые реализации rmпозволяют вам завершить команду +указанием, rmкоторое примет как можно больше аргументов:

find . -name .svn -exec rm -rf {} +

Последняя версия find / xargs использует print0, что заставляет find генерировать вывод, который используется \0как терминатор, а не как новая строка . Поскольку системы POSIX допускают любой символ, кроме \0имени файла, это действительно самый безопасный способ убедиться, что аргументы правильно переданы rmили приложение выполняется.

Кроме того, есть элемент, -execdirкоторый будет выполняться rmиз каталога, в котором был найден файл, а не из базового каталога, и элемент, -depthкоторый будет начинаться с глубины.

Калеб Педерсон
источник
31

Нет необходимости в каналах, xargs, exec или чем-либо еще:

find . -name .svn -delete

Редактировать: Просто шучу, очевидно, -deleteзвонки unlinkat()под капотом, поэтому он ведет себя как unlinkили rmdirи будет отказываться работать с каталогами, содержащими файлы.

AB
источник
54
Одна проблема - -deleteне трогать каталог, если он содержит файлы.
Xeoncross
2
Для предиката нет -forceили рекурсивного флага -delete, поэтому этот ответ бесполезен. Таким образом, он вернулся к |xargs rm -rf, менее некрасиво типа , то -execс его уродливыми заполнителей и точкой с запятой: -exec rm -rf '{}' \;.
Томаш Гандор
13

Уже есть много ответов для удаления .svn-директории. Но я хочу добавить, что вы можете избежать этих каталогов с самого начала, если вы сделаете экспорт вместо извлечения:

svn export <url>
Mnementh
источник
+1, нет необходимости повторять это, когда он уже встроен в SVN.
Powerlord
1
Единственная проблема, с которой я сталкиваюсь при таком подходе, заключается в том, что вы хотите сохранить неверсионные файлы в экспорте. Из документации svn: «Все локальные изменения будут сохранены, но файлы, не находящиеся под контролем версий, не будут скопированы».
raidfive
@raidfive: Обычно я предпочитаю, чтобы все соответствующие файлы находились под контролем версий, даже используемые библиотеки, чтобы проект работал «из коробки». Неверсионные файлы в этой настройке являются скомпилированными двоичными файлами, которые переделываются по цели в файле сборки. Но вы правы, если ваш проект использует файлы, не контролируемые версиями, экспорт не будет работать.
Mnementh
но ... мне нужен был более общий ответ. .SVN был просто самым распространенным примером, я отметил это в вопросе.
Итай Моав -Малимовка
12

Если вам не нравится видеть много

find: `./.svn': No such file or directory

предупреждения, затем используйте -depthпереключатель:

find . -depth -name .svn -exec rm -fr {} \;
lazy1
источник
10

В Windows вы можете использовать следующий скрипт реестра, чтобы добавить «Удалить папки SVN» в контекстное меню правой кнопки мыши. Запустите его в любом каталоге, содержащем эти надоедливые файлы.

Windows Registry Editor Version 5.00

[HKEY_LOCAL_MACHINE\SOFTWARE\Classes\Folder\shell\DeleteSVN]
@="Delete SVN Folders"

[HKEY_LOCAL_MACHINE\SOFTWARE\Classes\Folder\shell\DeleteSVN\command]
@="cmd.exe /c \"TITLE Removing SVN Folders in %1 && COLOR 9A && FOR /r \"%1\" %%f IN (.svn) DO RD /s /q \"%%f\" \""
Натан Тейлор
источник
Аккуратный трюк. Не полезно для ОП, но +1, потому что я был впечатлен!
rrhartjr
это круто. Спасибо. я знаю, что это супер старый, но что угодно. Я все равно люблю это.
Энтони
9

У тебя почти было это. Если вы хотите передать вывод команды в качестве параметров другому, вам нужно использовать xargs. Добавление -print0гарантирует, что скрипт может обрабатывать пути с пробелами:

find . -type d -name .svn -print0|xargs -0 rm -rf
soulmerge
источник
2
для некоторого резонанса то, что работало в конечном счете, находило. -name .svn | xargs rm -rf Ваша версия дала мне направление, хотя, спасибо
Итай Моав -Малимовка
4
find . -name .svn |xargs rm -rf
Итай Моав -Малимовка
источник
4

В качестве важной проблемы, когда вы хотите использовать оболочку для удаления папок .svn, вам нужен аргумент -depth, чтобы запретить команде find входить в только что удаленный каталог и отображать сообщения об ошибках, например, например:

"find: ./.svn: No such file or directory"

В результате вы можете использовать команду find, как показано ниже:

cd [dir_to_delete_svn_folders]
find . -depth -name .svn -exec rm -fr {} \;
fatihk
источник
Это то, что я искал и должен быть правильный ответ.
luckytaxi
3

Попробуй это:

find . -name .svn -exec rm -v {} \;

Узнайте больше о команде find на developerWorks .

Эдвард Дейл
источник
2

В качестве альтернативы, если вы хотите экспортировать копию без изменения рабочей копии, вы можете использовать rsync:

rsync -a --exclude .svn path/to/working/copy path/to/export
pimlottc
источник
1
Или используйте svn export / path / to / repository, который по сути делает то же самое.
Калеб Педерсон
Автор специально сказал, что не хочет использовать SVN; возможно, в его целевой среде svn не установлен.
pimlottc