Jak usunąć wszystkie katalogi .svn z moich katalogów aplikacji

192

Jedną z misji narzędzia eksportu, które mam w swojej aplikacji, jest oczyszczenie wszystkich .svnkatalogów z drzewa katalogów aplikacji. Szukam polecenia rekurencyjnego w powłoce systemu Linux, które przejdzie całe drzewo i usunie .svnpliki.

Nie używam eksportu, ponieważ ten skrypt będzie używany dla niektórych innych nazw plików / katalogów, które nie są związane z SVN. Próbowałem czegoś takiego:

find . -name .svn | rm -fr

Nie działało ...

Itay Moav-Malimovka
źródło
3
Twoje polecenie powinno działać, jeśli używasz „xargs rm -rf”
Peter van der Heijden,
1
Możesz również zmodyfikować komendę usuwania „rm -rfi”, aby upewnić się, że masz pewność, że chcesz usunąć katalogi.
bedwyr
Nie używaj jednak xargs .. będziesz mieć problemy z katalogami, w których są spacje itp. Użyj find, jak opisano poniżej.
John Hunt

Odpowiedzi:

438

Spróbuj tego:

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

Przed uruchomieniem takiego polecenia często lubię najpierw uruchomić to:

find . -name .svn -exec ls '{}' \;
Greg
źródło
43
Może być konieczne wstawienie {} w pojedynczym cudzysłowie, jeśli w katalogach może być spacja lub takie znaki: find . -name .svn -exec rm -rf '{}' \;
mtoloo
38
Ten test działa lepiej w mojej bash:find . -name .svn -exec echo {} \;
Fedir RYKHTIK
6
Uruchomienie echa / ls jako pierwszego jest „pro” dotykiem tej odpowiedzi. Każdy głupiec może zniszczyć system.
John Hunt
6
co robi {} \;zrobić?
Jon Mitten
3
Uruchamiając drugie polecenie, w tym lsotrzymuję entries prop-base props text-base tmpdane wyjściowe ...
Rasoul,
51

To, co napisałeś, wysyła listę nazw (i ścieżek) rozdzielonych znakiem nowej linii rm, ale rm nie wie, co zrobić z tym wejściem. Oczekuje tylko parametrów wiersza poleceń.

xargs pobiera dane wejściowe, zwykle oddzielone znakami nowej linii, i umieszcza je w wierszu poleceń, więc dodanie xargs sprawia, że ​​miałeś to, co miałeś do roboty:

find . -name .svn | xargs rm -fr

xargsjest na tyle inteligentny, że przekaże tylko tyle argumentów, rmile może zaakceptować. Tak więc, jeśli masz milion plików, może on działać rm1 000 000/65 000 razy (jeśli twoja powłoka może zaakceptować 65002 argumentów w wierszu poleceń {65k plików + 1 dla rm + 1 dla -fr}).

Jak słusznie zauważyli ludzie, działają również:

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

Obie pierwsze dwie -execformy wymagają rmusunięcia każdego folderu, więc jeśli miałbyś 1 000 000 folderów, rmbyłby wywoływany 1 000 000 razy. To z pewnością mniej niż idealne. Nowsze implementacje rmpozwalają na zakończenie polecenia ze +wskazaniem, rmktóre akceptuje jak najwięcej argumentów:

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

Ostatnia wersja find / xargs używa print0, co powoduje, że find generuje dane wyjściowe, które wykorzystują \0jako terminator zamiast nowego wiersza. Ponieważ systemy POSIX dopuszczają dowolny znak oprócz \0nazwy pliku, jest to naprawdę najbezpieczniejszy sposób, aby upewnić się, że argumenty są poprawnie przekazywane do rmaplikacji lub wykonywanej aplikacji.

Ponadto istnieje plik, -execdirktóry zostanie wykonany rmz katalogu, w którym plik został znaleziony, a nie z katalogu podstawowego, i -depthktóry rozpocznie głębokość jako pierwszy.

Kaleb Pederson
źródło
31

Nie ma potrzeby używania potoków, xargs, exec ani niczego innego:

find . -name .svn -delete

Edycja: Żartuję, ewidentnie -deletewywołuje unlinkat()pod maską, więc zachowuje się jak unlinklub rmdiri nie będzie działać na katalogach zawierających pliki.

AB
źródło
54
Jeden problem, -deletenie dotknie katalogu, jeśli zawiera on pliki.
Xeoncross
2
-forceDla -deletepredykatu nie ma flagi rekurencyjnej , więc ta odpowiedź jest bezużyteczna. Tak więc, jest to powrót do |xargs rm -rf, który jest mniej brzydki następnie wpisać -execz jego brzydkich zastępcze i średnikiem: -exec rm -rf '{}' \;.
Tomasz Gandor
13

Istnieje już wiele odpowiedzi na usunięcie katalogu .svn. Ale chcę dodać, że możesz uniknąć tych katalogów od samego początku, jeśli zrobisz eksport zamiast kasy:

svn export <url>
Memento
źródło
+1, nie ma potrzeby powtarzania tego, gdy jest już wbudowany w svn.
Powerlord,
1
Jedynym problemem, jaki widzę w przypadku tego podejścia, jest to, czy chcesz zachować niewersjonowane pliki podczas eksportu. Z dokumentów svn: „Wszystkie zmiany lokalne zostaną zachowane, ale pliki nieobjęte kontrolą wersji nie zostaną skopiowane”.
raidfive
@raidfive: Zwykle wolę mieć wszystkie odpowiednie pliki pod kontrolą wersji, nawet używane biblioteki, aby projekt działał od razu po wyjęciu z pudełka. Niewersjonowane pliki w tym ustawieniu są skompilowanymi plikami binarnymi, które są przekształcane przez cel w pliku kompilacji. Ale masz rację, jeśli twój projekt opiera się na plikach niepodlegających kontroli wersji, eksport nie działałby.
Mnementh,
ale ... Potrzebowałem bardziej ogólnej odpowiedzi. .Svn był tylko najczęstszym przykładem, zauważyłem to w pytaniu.
Itay Moav-Malimovka
12

Jeśli nie lubisz dużo

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

ostrzeżenia, a następnie użyj -depthprzełącznika:

find . -depth -name .svn -exec rm -fr {} \;
leniwy 1
źródło
10

W systemie Windows można użyć następującego skryptu rejestru, aby dodać „Usuń foldery SVN” do menu kontekstowego prawym przyciskiem myszy. Uruchom go w dowolnym katalogu zawierającym te nieznośne pliki.

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\" \""
Nathan Taylor
źródło
Sztuczka. Nie jest to pomocne dla PO, ale daje +1, ponieważ byłem pod wrażeniem!
rrhartjr
to jest niesamowite. dzięki. wiem, że to jest bardzo stare, ale cokolwiek. i tak to kocham.
Anthony
9

Prawie to miałeś. Jeśli chcesz przekazać dane wyjściowe polecenia jako parametry do innego, musisz użyć xargs. Dodanie -print0upewnia się, że skrypt obsługuje ścieżki ze spacjami:

find . -type d -name .svn -print0|xargs -0 rm -rf
soulmerge
źródło
2
przez pewien rezon okazało się, co ostatecznie zadziałało. -name .svn | xargs rm -rf Twoja wersja podała mi jednak kierunek, dzięki
Itay Moav -Malimovka 18.08.2009
4
find . -name .svn |xargs rm -rf
Itay Moav-Malimovka
źródło
4

Jako ważny problem, gdy chcesz użyć powłoki do usunięcia folderów .svn, potrzebujesz argumentu -depth, aby uniemożliwić komendzie find wejście do właśnie usuniętego katalogu i wyświetlenie komunikatów o błędach, takich jak np.

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

W rezultacie możesz użyć polecenia find, jak poniżej:

cd [dir_to_delete_svn_folders]
find . -depth -name .svn -exec rm -fr {} \;
fatihk
źródło
Właśnie tego szukałem i powinienem być poprawną odpowiedzią.
luckytaxi
3

Spróbuj tego:

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

Przeczytaj więcej o poleceniu find na developerWorks .

Edward Dale
źródło
2

Alternatywnie, jeśli chcesz wyeksportować kopię bez modyfikowania kopii roboczej, możesz użyć rsync:

rsync -a --exclude .svn path/to/working/copy path/to/export
pimlottc
źródło
1
Lub użyj svn export / path / to / repository, który zasadniczo robi to samo.
Kaleb Pederson
Autor wyraźnie powiedział, że nie chce używać svn; być może jego docelowe środowisko nie ma zainstalowanej svn.
pimlottc,