Як видалити всі .svn каталоги з моїх каталогів програм


192

Однією з місій інструменту експорту, який я маю в своїй програмі, є очищення всіх .svnкаталогів з мого дерева каталогів додатків. Я шукаю рекурсивну команду в оболонці Linux, яка буде обходити все дерево та видаляти .svnфайли.

Я не використовую експорт, оскільки цей скрипт буде використовуватися для деяких інших імен файлів / директорій, які не мають відношення до SVN. Я спробував щось на кшталт:

find . -name .svn | rm -fr

Не вийшло ...


3
Ваша команда повинна працювати, якщо ви використовуєте 'xargs rm -rf'
Пітер ван дер Хейден

1
Ви також можете змінити команду видалення "rm -rfi" лише для того, щоб впевнитись, що хочете видалити каталоги.
bedwyr

Не використовуйте xargs, хоча .. у вас виникнуть проблеми з каталогами, в яких є пробіли тощо. Використовуйте пошук, як описано нижче.
Джон Хант

Відповіді:


438

Спробуйте це:

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

Перш ніж виконувати таку команду, я часто люблю запускати цю першу:

find . -name .svn -exec ls '{}' \;

43
Можливо, вам доведеться ввести {} в одну цитату, якщо в каталогах може бути пробіл або такі символи: find . -name .svn -exec rm -rf '{}' \;
mtoloo

38
Цей тест краще працює в моєму find . -name .svn -exec echo {} \;
башті

6
Запуск ехо / лс спочатку - "про" дотик до цієї відповіді. Будь-який дурень може зірвати систему.
Джон Хант

6
що робить {} \;?
Джон Міттен

3
Запустивши другу команду в тому числі ls, я отримую entries 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, завдяки чому пошук генерує вихід, який використовується \0як термінатор, а не як новий рядок. Оскільки системи POSIX дозволяють використовувати будь-які символи, крім \0імені файлу, це справді найбезпечніший спосіб переконатися в правильності передачі аргументів rmабо в застосуванні програми.

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


31

Не потрібно труб, xargs, exec чи нічого:

find . -name .svn -delete

Edit: Просто жартую, по- видимому , -deleteвикликає unlinkat()під капотом, тому він поводиться як unlinkабо rmdirі відмовляються працювати на каталоги , що містять файли.


54
Одна з проблем - -deleteне торкнеться каталогу, якщо він містить файли.
Xeoncross

2
Немає -forceабо рекурсивного прапора для -deleteпредиката, тому ця відповідь марний. Таким чином, він повернувся до |xargs rm -rf, менш некрасиво типу , то -execз його потворними наповнювачів і точкою з коми: -exec rm -rf '{}' \;.
Томаш Гандор

13

Для видалення каталогу .svn вже існує багато відповідей. Але я хочу додати, що ви можете уникати цих каталогів з самого початку, якщо зробите експорт замість каси:

svn export <url>

+1, це не потрібно переробляти, коли він уже вбудований у svn.
Powerlord

1
Єдине питання, яке я бачу при такому підході, це якщо ви хочете зберегти неперевершені файли в експорті. З документа svv "Усі локальні зміни будуть збережені, але файли, які не перебувають під контролем версій, не будуть скопійовані".
raidfive

@raidfive: Зазвичай я вважаю за краще мати всі відповідні файли під контролем версій, навіть використовувані бібліотеки, щоб проект працював поза коробкою. Неперевершені файли в цій установці складаються у двійкові файли, які перечитуються ціллю у файлі збірки. Але ви праві, якщо ваш проект покладається на файли, які не перебувають під контролем версій, експорт не буде працювати.
Менмент

але ... мені потрібна була більш загальна відповідь. .Svn був просто найпоширенішим прикладом, я це зазначив у питанні.
Itay Moav -Malimovka

12

Якщо вам не подобається бачити багато

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

попередження, потім використовуйте -depthперемикач:

find . -depth -name .svn -exec rm -fr {} \;

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

2
для деякого резона було знайдено те, що спрацювало. -name .svn | xargs rm -rf Ваша версія дала мені вказівку, хоча, дякую
Itay Moav -Malimovka


4

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

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

Як результат, ви можете використовувати команду find як нижче:

cd [dir_to_delete_svn_folders]
find . -depth -name .svn -exec rm -fr {} \;

Це те, що я шукав, і має бути правильною відповіддю.
luckytaxi


2

Якщо ви хочете експортувати копію без зміни робочої копії, ви можете використовувати rsync:

rsync -a --exclude .svn path/to/working/copy path/to/export

1
Або використовувати svn export / path / to / repository, що по суті робить те саме.
Калеб Педерсон

Автор спеціально сказав, що не хоче використовувати svn; можливо, його цільове середовище не встановлено svn.
pimlottc
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.