Ответ 1
Попробуйте следующее:
find . -name .svn -exec rm -rf '{}' \;
Прежде чем запускать такую команду, мне часто нравится сначала ее запускать:
find . -name .svn -exec ls '{}' \;
Одна из задач инструмента экспорта, который у меня есть в моем приложении, состоит в том, чтобы очистить все каталоги .svn
от дерева каталогов приложений. Я ищу рекурсивную команду в оболочке Linux, которая пересечет все дерево и удалит файлы .svn
.
Я не использую экспорт, так как этот script будет использоваться для некоторых других имен файлов/каталогов, которые не связаны с SVN. Я попробовал что-то вроде:
find . -name .svn | rm -fr
Это не сработало...
Попробуйте следующее:
find . -name .svn -exec rm -rf '{}' \;
Прежде чем запускать такую команду, мне часто нравится сначала ее запускать:
find . -name .svn -exec ls '{}' \;
То, что вы написали, отправляет список разделенных имен новой строки (и путей) в rm
, но rm не знает, что делать с этим вводом. Он ожидает только параметров командной строки.
xargs
принимает ввод, обычно разделенный символами новой строки, и помещает их в командную строку, поэтому добавление xargs делает то, что вы наработали:
find . -name .svn | xargs rm -fr
xargs
достаточно интеллектуальный, что он будет передавать столько аргументов rm
, сколько он может принять. Таким образом, если у вас было миллион файлов, он мог бы запускать rm
1 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
, который начнет сначала сначала.
Нет необходимости в каналах, xargs, exec или что-либо:
find . -name .svn -delete
Изменить: Просто шутите, очевидно, -delete
вызывает unlinkat()
под капотом, поэтому он ведет себя как unlink
или rmdir
и откажется работать в каталогах, содержащих файлы.
Если вам не нравится видеть много
find: `./.svn': No such file or directory
затем используйте переключатель -depth
:
find . -depth -name .svn -exec rm -fr {} \;
Уже существует много ответов на удаление каталога .svn. Но я хочу добавить, что вы можете избежать этих каталогов с самого начала, если вы делаете экспорт вместо проверки:
svn export <url>
У тебя это было почти. Если вы хотите передать вывод команды в качестве параметров в другую, вам нужно будет использовать xargs. Добавление -print0
гарантирует, что script может обрабатывать пути с пробелами:
find . -type d -name .svn -print0|xargs -0 rm -rf
В Windows вы можете использовать следующий реестр script, чтобы добавить "Удалить папки 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\" \""
find . -name .svn |xargs rm -rf
В качестве важной проблемы, когда вы хотите использовать оболочку для удаления папок .svn, вам нужен аргумент -depth, чтобы команда find не входила в только что удаленный каталог и отображала сообщения об ошибках, например,
"find: ./.svn: No such file or directory"
В результате вы можете использовать команду find, как показано ниже:
cd [dir_to_delete_svn_folders]
find . -depth -name .svn -exec rm -fr {} \;
Попробуйте следующее:
find . -name .svn -exec rm -v {} \;
Подробнее о команде find в developerWorks.
В качестве альтернативы, если вы хотите экспортировать копию без изменения рабочей копии, вы можете использовать rsync:
rsync -a --exclude .svn path/to/working/copy path/to/export