Як видалити всі .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.