rm -rf wszystkie pliki i wszystkie ukryte pliki bez. & .. błąd


82

rm -rf /some/path/* usuwa wszystkie nie ukryte pliki z tego katalogu (i podkatalogów).

rm -rf /some/path/.* usuwa wszystkie ukryte pliki z tego katalogu (ale nie katalogów), a także wyświetla następujący błąd / ostrzeżenie:

rm: cannot remove directory: `/some/dir/.'
rm: cannot remove directory: `/some/dir/..'

Jaki jest właściwy sposób usuwania wszystkich ukrytych i nie ukrytych plików i folderów rekurencyjnie w katalogu docelowym bez otrzymywania ostrzeżenia / błędu dotyczącego .i ..?

Odpowiedzi:


39

Zawsze możesz wysyłać komunikaty o błędach na adres /dev/null

rm -rf /some/path/.* 2> /dev/null

Możesz także

rm -rf /some/path/
mkdir /some/path/

... wtedy nie będziesz musiał zawracać sobie głowy ukrytymi plikami.


2
Ale co, jeśli chcę tylko usunąć ukryte pliki?
CMCDragonkai

@CMCDragonkai to powinno być inne pytanie, ale rozwiązanie znajdziesz w odpowiedzi Gillesa ( rm ..?* .[!.]*powinno to zrobić).
evilsoup

15
Brak usuwania i ponownego tworzenia katalogu stwarza ryzyko, że uprawnienia do plików nie będą odtąd odpowiednie (szczególnie ważne w środowiskach serwerowych). Kto może utworzyć folder z takimi samymi uprawnieniami jak wcześniej automatycznie?
Yo Ludke,

1
@YoLudke Masz całkowitą rację, w wielu sytuacjach nie ma to znaczenia, ale usunięcie folderu i odtworzenie nie jest semantycznie równoważne z opróżnieniem tego folderu; więc bądź ostrożny!
Thomas

Usunięcie katalogu nie zawsze jest możliwe. W moim przypadku katalog jest woluminem dokującym i chociaż mogę robić wszystko, co chcę w wolumenie, nie mogę zmienić samego wolumenu z kontenera.
dovidweisz

85

*dopasowuje wszystkie pliki bez kropek, .[!.]*dopasowuje wszystkie pliki kropek oprócz .i pliki, których nazwa zaczyna się od .., i ..?*pasuje do wszystkich plików kropek oprócz ... Razem pasują do wszystkich plików innych niż .i ... Jeśli którykolwiek z tych trzech wzorów nic nie pasuje, rozwija się do siebie; rm -fnie przejmuje się nieistniejącymi argumentami, więc to nie ma znaczenia.

rm -rf ..?* .[!.]* *

Możesz także użyć find. Jest to bardziej złożone, ale ma tę zaletę, że działa nawet wtedy, gdy jest tak wiele plików, że powyższe symbole wieloznaczne wykraczają poza limit długości wiersza poleceń systemu.

find . -name . -o -prune -exec rm -rf -- {} +

Usunięcie i ponowne utworzenie katalogu może być łatwiejsze. Ma to tę zaletę (lub wadę, że zależnie od przypadku), że powoduje powstanie pustego katalogu, nawet jeśli inny program jednocześnie tworzy pliki w oryginalnym katalogu.


8
To powinna być zaakceptowana odpowiedź, ponieważ zapobiega przemieszczaniu się rodziców i możliwemu usunięciu.
rbellamy

findAlternatywa powraca „sukces”, nawet jeśli jakiś plik nie został pomyślnie usunięty; nie dobre dla skryptu.
Franklin Yu

W odniesieniu do drugiego findpolecenia strona man dla find stwierdza: „Ponieważ -delete oznacza -depth, nie można z powodzeniem używać -prune i -delete razem”. - jeszcze korzystasz -prune -delete?
Doktor J

@DoktorJ Rzeczywiście, -prunenic tu nie robi. A po przeczytaniu widzę, że nie odpowiedziałem poprawnie na pytanie: starałem się nie powtarzać, ale pytanie wyraźnie prosi o rekurencyjne usunięcie. Poprawiłem swoją odpowiedź.
Gilles

2
@haylem W zsh musisz pisać .[^.]*zamiast .[!.]*gdy włączone jest podstawianie historii (co jest domyślnie przypadkiem interaktywnie, ale nie w skryptach), ponieważ zsh analizuje !jako odwołanie do historii. Ale w zsh nie potrzebujesz tego w pierwszej kolejności, możesz po prostu użyć *(D)plików kropek (bez .lub ..) w dopasowaniu do znaku wieloznacznego.
Gilles

21

Właśnie zdałem sobie sprawę, że jest to najwygodniejszy sposób w większości dystrybucji Linuksa:

ls -A1 | xargs rm -rf

gdzie

-A= wypisz wszystko oprócz . i..

-1 = umieść każdy element w jednym wierszu


4
Minusem, który widzę jest to: musisz „cd” do katalogu, aby to zrobić.
kumar

ls -A1 /your/path/ | xargs rm -rfnależy zastosować
godzillante

nope..it nie pomaga - na przykład: ls -A1 ~ / test / | xargs rm -rf to polecenie usuwa pliki, w których aktualnie jestem „cd”, nie ma w katalogu ~ / test.
kumar

5
Nie działa, jeśli którakolwiek z nazw plików zawiera spacje, znaki nowej linii, cudzysłowy lub ukośniki odwrotne.
Stéphane Chazelas,

1
-1 Z powodu powyższego komentarza. ↑↑↑↑↑↑ SIEM
coś Coś

15

Zmień dotglobopcję powłoki i użyj *lub użyj czegoś podobnego find.

find somedir -mindepth 1 -delete

2
Lub możesz po prostu, rm -rf /some/dira następnie utworzyć nowy pusty katalog na jego miejscu.
tripleee

Jak dotąd najlepsza opcja. Bardzo bezpieczne, ponieważ wyraźnie określasz ścieżkę katalogu.
Yanick Girouard

4

Powinno to działać tak samo jak odpowiedź @Gilles, ale bardziej kompaktowe:

rm -rf {,.[!.],..?}*

lub

rm -rf dir/to/files/{,.[!.],..?}*

powinien również dodać ifdo użycia w skryptach, aby być bezpiecznym:

if [ -d "$DIR" ]; then
    rm -rf ${DIR}/{,.[!.],..?}*
fi

1
Co dziwne, jako alias bash na Ubuntu 16.04 LTS poprzednia odpowiedź nie działała. Jednak alias cleandir='rm -rf {,.[!.],..?}*'tak jest.
Steven Ventimiglia

3

Znajdź to twój przyjaciel.

find ! -name '.' ! -name '..' -delete

% find ! -name '.' ! -name '..'
./test
./test4
./test4/.test6
./test3
./.test5
./test2
% find ! -name '.' ! -name '..' -delete    
% find ! -name '.' ! -name '..'     
%             

Jeśli chcesz użyć rekurencyjnie przeszukaj coś innego w bieżącym katalogu ($ PWD), dodaj ścieżkę bezpośrednio po findpoleceniu; np find /path ! -name '.' ! -name '..' -delete. Jeśli chcesz tylko obniżyć nliczbę katalogów, użyj -maxdepth nopcji tuż po /pathparametrze.

Powyższe polecenie zostało przetestowane w systemie Ubuntu 13.04. Prawdopodobnie będzie działał na innych, nowoczesnych systemach Linux.


aby usunąć wszystkie katalogi w bieżącym katalogu, co możesz zrobićfind . ! -name '.' ! -name '..' -type d -delete
Andy

2

Jaki jest właściwy sposób usuwania wszystkich ukrytych i nie ukrytych plików i folderów rekurencyjnie w katalogu docelowym bez otrzymywania ostrzeżenia / błędu dotyczącego. i ..?

Zakładając, że dany katalog jest ./dir, to

rm -rf ./dir

usunie wszystkie pliki, w ./dirtym ukryte pliki i katalogi, rekurencyjnie, łącznie z ./dirsamym katalogiem.

Jeśli nie chcesz usuwać samego katalogu, możesz po prostu ponownie go utworzyć lub użyć

find ./dir -mindepth 1 -delete

lub jeśli findnie wspierasz -delete,

find ./dir -mindepth 1 -depth -exec rm -rf {} ';'

Korzystanie -mindepth 1pozwala zachować katalog najwyższego poziomu ./dir.


należy to oznaczyć jako najlepszą odpowiedź
kitingChris

1

Proponuję eksperymentować z

Turn ON kropek (ukryte)

  • zestaw dotglob

    shopt -s dotglob

Turn OFF kropki

  • nieoprawny dotglob

    shopt -u dotglob

Ta metoda działała dokładnie tak, jak chciałem dla polecenia kopiowania, w którym brakowało ukrytych katalogów.

    shopt -s    dotglob
    cp    -rvn  ./$from/*  ./$too/
    shopt -u    dotglob

Więc zrobiłem usunąć (usuń), a ups ...

    shopt -s    dotglob
    rm -fr ../message_splitter--044a/*
    shopt -u    dotglob

... to też działa!

Przyszło mi do głowy, że drogi czytelniku nie widzę message_splitterkatalogu. W dowolny sposób ma .svnfolder, który należy usunąć i skopiować do.

Ze manstrony ...

dotglob Jeśli ustawione, bash zawiera nazwy plików rozpoczynające się od `. ' w wynikach rozwinięcia nazwy ścieżki.

Bibliografia:


-2

Wypróbuj ten kod:

Dirlist=``find /some/path/ -type d -name '.[^.]*'`
for HiddenDir in $Dirlist
do
    rm -rf $HiddenDir
done
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.