Jak usunąć wszystkie pliki oprócz jednego w Uniksie? [duplikować]

Odpowiedzi:

20
ls * | grep -v dont_delete_this_file | xargs rm -rf 

Przykład:

mkdir test && cd test
touch test1
touch test2
touch test3
touch test4
touch test5

Aby usunąć wszystkie pliki oprócz „test2”:

ls * | grep -v test2 | xargs rm -rf

Zatem wyjściem „ls” jest:

test2

EDYTOWAĆ:

Dziękuję za komentarz. Jeśli katalog zawiera niektóre pliki ze spacjami:

mkdir test && cd test
touch "test 1"
touch "test 2"
touch "test 3"
touch "test 4"
touch "test 5"

Możesz użyć (z bash):

rm !("test 1"|"test 4")

Wyjście „ls”:

test 1
test 4
Sandro Munda
źródło
Miałem zamiar zrobić bardzo podobnie przy użyciu find, ale twój działa i byłeś szybszy. +1
Rory Alsop
2
to się nie powiedzie, jeśli masz pliki ze spacjami w ich nazwach.
Mat
Do obsługi nazw plików ze spacjami można użyćls -1 | grep -v do_not_delete | xargs -I files rm "files"
sebhofer
8

Zakładając, że używasz powłoki bash (najczęstszy przypadek), możesz użyć symbolu globowania negacji (rozwinięcia nazwy ścieżki):

rm -rf !(myfile.txt)

Używa to rozszerzonego globowania, więc najpierw musisz włączyć:

shopt -s extglob
Lauren
źródło
1
 cp myfile.txt somewhere_else;
 rm -rf *
 cp somewhere_else/myfile.txt .
Rayfleck
źródło
1
ln myfile.txt .myfile.txt && rm -rf * && mv .myfile.txt myfile.txt
jlliagre
źródło
0

W przypadku rekurencji rmnależy wykonać rekursję findi wykluczyć pliki, które chcesz zachować (lub grep, ale może to spowodować problemy z białymi znakami). W przypadku globu powłoki współczesne powłoki mają wzorce globu, których można użyć do wykluczenia plików; można to połączyć z rekurencją globalną na poziomie powłoki, jeśli jest dostępna (np. zshma rm **/*~foo/bar- pamiętaj, że może to prowadzić do ograniczenia długości argumentów dla dużych drzew katalogów).

geekozaur
źródło