Usuń wszystkie podkatalogi oprócz jednego

10

Załóżmy, że w bieżącym katalogu znajduje się wiele podkatalogów, a jeden nazywa się A.

Jak usunąć wszystkie podkatalogi oprócz A z Bash?

anon
źródło

Odpowiedzi:

23

Bash rozszerzył globowanie (pierwszy test, a następnie usunięcie echa):

shopt -s extglob
echo rm -rf !(A)
TheBonsai
źródło
(zanim zapomnę - możesz wyłączyć uzupełnianie historii stylu CSH, w Bash3 jest błąd podczas ignorowania! (. set + H
+1 Bash, jeśli jest pełen niespodzianek! Czasami są tacy mili jak ten.
Aleksandr Levchuk
Wauw naprawdę bardzo miło! Działa zgodnie z oczekiwaniami. Z shopt | grep extMożesz sprawdzić, czy wtyczka jest włączona.
niebezpieczne89
14
find -maxdepth 1 -type d -not -name A -not -name "." -exec rm -ir {} \;
dotjoe
źródło
10

Co powiesz na:

mv A /tmp/
rm * -rf
mv /tmp/A .

Pozwala to uniknąć „rzadkości” literówki w innych poleceniach.

Brent
źródło
1
+1 za robienie rozsądnych rzeczy zamiast mieć nadzieję, że narzędzia są wystarczająco inteligentne. pewnej nocy, kiedy dopiero uczyłem się Linuksa, skopiowałem jądro do / tmp przed pierwszą rekompilacją. nie powiodło się, ale usunęło stare, więc powiedziałem „nie przejmuj się, mam kopię” tylko po to, by stwierdzić, że zadanie cron o północy usunęło go z każdym plikiem starszym niż tydzień w / tmp! Musiałem ponownie skompilować ponownie i tym razem zrób to dobrze, albo zrestartuj mnie!
Javier
najlepsza odpowiedź wysłana :)
warren
3

Coś jak

find . -type d -not -name A -exec rm -ir {} \;

powinieneś zrobić.

edytować

Tak powinno być

find . -type d -maxdepth 1 -not -name A -exec rm -ir {} \;

aby zapobiec findod recursing poniżej A.

agnul
źródło
3
Spowodowałoby to jednak również usunięcie podkatalogów poniżej A, takich jak A / foo i A / bar, ale zachowałoby A / A.
TCampbell
Fajne! Pytania i odpowiedzi migrują z SO do SF ... ale moja powyższa edycja została utracona ...
agnul
Lepiej jest zamienić maxdepth i wpisać takie argumenty: find. -maxdepth 1 -typ d -not -name A -exec rm -ir {} \;
Spawnrider
1

zwykle robię to, pracując nad poleceniem ls, które najpierw to robi. nie jestem na maszynie uniksowej, ale coś takiego:

ls -lda "[^ A]"

Po prawidłowym ustawieniu potok do polecenia

ls -lda "[^ A]" | xargs rm -rf

Jeśli powyższe wyrażenie regularne jest błędne, możesz je edytować powyżej ...

Tim Hoolihan
źródło
Nie powinieneś analizować ls: mywiki.wooledge.org/ParsingLs
wstrzymano do odwołania.
1

Jeśli chcesz być bardziej elastyczny, ale manualny, możesz:

ls > /tmp/foo
edit /tmp/foo as you like
xargs -a /tmp/foo rm -r

W ten sposób możesz wykonywać ogólne munging.

Joe Beda
źródło
1

Oto jeden sposób. Uważaj jednak na tego rodzaju rzeczy, jest on tak potężny, że można go używać tylko dla dobra lub zła ...

znajdź * typ d | grep -v "^ A" | xargs rm -rf
Don Branson
źródło
1

Nie używaj find, ponieważ niektórzy ludzie pokazali z -exec i rm bez przekazywania -print0, aby znaleźć i -0 do xargs. Będzie mylić nazwy plików ze spacjami lub znakami nowej linii:

$ mkdir 'foo foo'
$ mkdir foo$'\n'foo 
$ find . -type d -exec rm -ir {} \;
rm: cannot remove directory `.'
rm: remove directory `./foo\nfoo'? y
find: `./foo\nfoo': No such file or directory
rm: remove directory `./foo foo'? y
find: `./foo foo': No such file or directory

Zamiast tego użyj find -print0 z xargs -0, „-exec command {} +” lub -delete, jeśli twoje znalezisko to obsługuje.

Kyle Brandt
źródło
1

Oprócz wcześniejszego przykładu:

find -maxdepth 1 -type d -not -name A -not -name "." -exec rm -ir {} \;

możesz także:

find some/subdir -mindepth 1 -maxdepth 1 -type d -not -name A -exec rm -ir {} \;

aby uniknąć konieczności cd some/subdirnajpierw.

Lurchman
źródło