Usuń wszystkie katalogi z katalogu nadrzędnego oprócz jednego i jego potomków


8

struktura katalogów

Chcę usunąć katalog B i D. Ale chcę zachować C i wszystkie jego potomne pliki i katalogi. Jaka jest komenda usuwania wszystkich katalogów potomnych katalogu nadrzędnego oprócz jednego katalogu i jego potomków.

Pomoc doceniona.


czy katalogi, które chcesz usunąć, są puste?
Elder Geek


Co z plikami znajdującymi się bezpośrednio w katalogu nadrzędnym ( Aw twoim przykładzie)? Usunąć je również czy zachować?
Bajt Dowódca

Pyta Byte Commander, czy w A są jakieś pliki? czy tylko katalogi? Czy chcesz usunąć zwykłe pliki z katalogu A czy tylko katalogi?
Sergiy Kolodyazhnyy

Odpowiedzi:


6

To, czego chcesz, to polecenie:

find ~/TESTDIR -mindepth 1 -maxdepth 1 -type d -not \( -name "keepMe" \) -exec rm -rf {} \;

Próbny:

# List what's inside directory we want to remove
$ ls
file1  file2  keepMe/  removeA/  removeB/
# Testing what find gives without removing
$ find ~/TESTDIR -mindepth 1 -type d -not \( -name "keepMe" \)               
/home/xieerqi/TESTDIR/removeA
/home/xieerqi/TESTDIR/removeB
# Actual removal and testls
$ find ~/TESTDIR -mindepth 1 -maxdepth 1 -type d -not \( -name "keepMe" \) -exec rm -rf {} \;
$ ls
file1  file2  keepMe/

Wyjaśnienie:

  • find DIRECTORY wywołaj polecenie find, aby operować na KATALOGU
  • -mindepth 1 : działa tylko z zawartością katalogu, unikaj samego katalogu, który jest na poziomie 0
  • -maxdepth 1: zapobiega zejściu do podkatalogów ( rm -rfzresztą jest rekurencyjny, więc nie musimy schodzić do podkatalogów, aby je usunąć)
  • -type d : szukaj tylko katalogów
  • -not \( -name "keepMe" \) zignoruj ​​element o nazwie, którą chcesz zachować
  • -exec rm -rf {} \; usuń każdy znaleziony element

Świetne wyjaśnienie. Jednak dla mnie za dużo naciśnięć klawiszy ...
Starszy Geek

1
findjest dobrym przyjacielem, ale Bash fori testlepsi przyjaciele ...>: - D
Byte Commander

8

Korzystanie z rozszerzonych funkcji globalnej powłoki bash (które są domyślnie włączone w bieżących instalacjach Ubuntu), podane

$ tree A
A
├── B
├── C
│   ├── ac1
│   └── ac2
└── D

5 directories, 0 files

możesz zająć się wszystkim z wyłączeniem Ci jego zawartością za pomocą wyrażenia glob, A/!(C)tj

$ echo A/!(C)
A/B A/D

Aby usunąć wszystko oprócz katalogu Ci jego zawartości, możesz po prostu użyć

rm -rf A/!(C)

odejście

$ tree A
A
└── C
    ├── ac1
    └── ac2

3 directories, 0 files

To niesamowite wiedzieć o tej funkcji. Działa świetnie po ssh i ręcznym uruchomieniu, ale pojawia się komunikat „” -bash: linia 1: błąd składni w pobliżu nieoczekiwanego tokena, ('"gdy uruchamiam go zdalnie za pośrednictwem ssh $VM_ADDRESS "rm -rf $APP_FOLDER/!(node_modules)". Masz jakieś pomysły? Bardzo dziękuję.
Renato Gama

@renatoargh extglobopcja powłoki jest włączona tylko dla powłok interaktywnych - nie wiem, czy można zmusić sshdo zrobienia tego
steeldriver

5

Jednym prostym sposobem byłoby użycie trash-cli

możesz go zainstalować za pomocą sudo apt-get install trash-cli

po zainstalowaniu możesz przejść do katalogu nadrzędnego A, cd /Aa następnie wydać polecenie, w trash B Dktórym B i D są katalogami, które chcesz usunąć (trafią do kosza na dysku, na którym się znajdują, więc jeśli popełnisz błąd, możesz to zrobić odzyskać pliki)

Testowane pod Ubuntu 16.04 i 14.04


Czy można to uprościć za pomocą czegoś takiego trash ! C?
Sergiy Kolodyazhnyy

@Serg Nope trash: cannot trash non existent ! ''
Starszy Geek

@Serg and C zostaje zniszczony ...
Starszy Geek

Znaleziono: stackoverflow.com/q/216995/3701431 Wymaga to extglobjednak włączenia .
Sergiy Kolodyazhnyy

@Serg W zależności od wykonywanej pracy może to być bardzo przydatne! ;-)
Starszy Geek

4

Wystarczy użyć forpętli Basha i testprzefiltrować pożądane katalogi oraz rm -rfpolecenie rekurencyjnego usuwania katalogów, tak jak to:

for x in /path/to/parent/*; do test "$x" != "dir_survive" && rm -rf "$x"; done

Powoduje to iterację wszystkich elementów (plików i katalogów) w środku /path/to/parent/i rekurencyjnie usuwa element, jeśli jego nazwa nie jest równa dir_survive. Jeśli katalog nadrzędny jest katalogiem bieżącym, możesz pisać tylko *jako ścieżkę.

Jeśli nie masz pewności i chcesz przetestować, które elementy zostaną najpierw usunięte bez podejmowania jakichkolwiek działań, po prostu zamień rm -rfpowyższe polecenie na, echoa wyświetli tylko kandydatów do usunięcia.

Oto przykładowy przebieg:

$ tree
.
├── dir1
│   ├── subdir1
│   │   ├── file1
│   │   └── file2
│   └── subdir2
│       ├── file1
│       └── file2
├── dir2
│   ├── subdir1
│   │   ├── file1
│   │   └── file2
│   └── subdir2
│       ├── file1
│       └── file2
└── dir_survive
    ├── subdir1
    │   ├── file1
    │   └── file2
    └── subdir2
        ├── file1
        └── file2

9 directories, 12 files

$ for x in *; do test "$x" != "dir_survive" && rm -rf "$x"; done

$ tree
.
└── dir_survive
    ├── subdir1
    │   ├── file1
    │   └── file2
    └── subdir2
        ├── file1
        └── file2

3 directories, 4 files
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.