Jak usunąć wszystkie ukryte pliki i katalogi za pomocą Bash?

28

Oczywiste rozwiązanie generuje kod wyjścia 1:

bash$ rm -rf .*
rm: cannot remove directory `.'
rm: cannot remove directory `..'
bash$ echo $?
1

Jednym z możliwych rozwiązań będzie pominięcie „.” i „..”, ale usuwają tylko pliki, których nazwy są dłuższe niż 3 znaki:

bash$ rm -f .??*
Yonatan Broza
źródło
Cóż, jeśli nie martwisz się zbytnio brakiem możliwości usunięcia. I .. to kogo to obchodzi? chyba że martwisz się o brzydkie wyniki w skrypcie, myślę, że oczywistym rozwiązaniem jest mniej pisanie na maszynie niż inni szczerze.
Matt
Tylko żebyś wiedział ... i. nie są plikami. Są to odniesienia do katalogów. . (tylko jedna kropka) to bieżący katalog, a .. (dwie kropki) to link do katalogu o jeden poziom wyżej. Na przykład, jeśli cd / home / user,. jest równe / home / user i .. to / home / Innymi słowy, nie można usunąć pliku. i .. (.?)
fuzja
Dzięki za komentarz Matt. Często używam polecenia w skryptach z funkcją sprawdzania kodu wyjścia dla każdego polecenia (zestaw -e). W takich przypadkach konieczny jest orientacyjny kod wyjścia.
Yonatan Broza
Nie ma w tym nic nieodłącznego. i .., który chroni je przed usunięciem za pomocą rm -rf. To tylko mechanizm ochronny dodany do nowoczesnych odmian rm.
kubańczyk
I zawsze jest rm -rf. * || true, jeśli chcesz obejść zachowanie zestawu -e dla tej jednej instrukcji.
Domingo Ignacio Galdos

Odpowiedzi:

34
rm -rf. [^.]. ?? *

Powinien złapać wszystkie przypadki. . ?? * będzie pasować tylko do ponad 3-znakowych nazw plików (jak wyjaśniono w poprzedniej odpowiedzi), a. [^.] Będzie przechwytywał dowolne dwa znaki (inne niż ...).

Russell Heilling
źródło
Dziękuję za odpowiedź! Na tej podstawie znalazłem też krótszą wersję „rm -rf. [^.] *”.
Yonatan Broza
4
Uważaj na tę krótszą wersję, da ona podobne, ale nie identyczne wyniki. Nie będzie pasować do nazw z dwoma kropkami z przodu (np. „... /”, które czasami widać, ukrywając rootkity itp.)
Russell Heilling,
I uważaj, aby wykonać kontrolę PWD lub stracić wszystkie ustawienia :)
kommradHomer
Wydaje się, że to nie działa zsh. Jakieś sugestie?
ryanjdillon
Z zshdomyślnie pusta wieloznaczny mecz jest traktowany jako błąd; podczas gdy z bashnim jest po prostu przekazywane bez zmian. Aby zshzachować się tak samo, możesz użyć poleceniaunsetopt nomatch
Russell Heilling
1
find -path './.*' -delete

To pasuje do wszystkich plików w bieżącym katalogu, które zaczynają się od a, .i usuwa je rekurencyjnie. Pliki ukryte w nie ukrytych katalogach nie są dotykane.

W przypadku, gdy naprawdę chcesz usunąć wszystko z katalogu, find -deletewystarczy.

Fritz
źródło
Spowoduje to usunięcie wszystkiego, nie tylko tych wpisów zaczynających się od.
kasperd
Och, wydaje mi się, że źle odczytałem pytanie jako „usuń wszystko, w tym ukryte pliki” ... Cóż, moje złe.
Fritz,
@kasperd Dzięki, teraz powinno faktycznie odpowiedzieć na pytanie.
Fritz,
0

najlepszym sposobem jest prawdopodobnie:

  • odnaleźć . -iname. * -maxdepth 1 -type f -exec rm {} \;

zmień rm na ls -l, jeśli chcesz tylko zobaczyć, co zostanie usunięte, aby uzyskać szczegółowe informacje, możesz dodać opcję -v do rm

  • -type f opcje każe komendzie find szukać tylko plików (pomiń katalogi, linki itp.)
  • -maxdepth 1 mówi find, aby nie schodzić do podkatalogów

ps. nie zapomnij o zakończeniu „\;”


źródło
1
Ostrożny! Masz na myśli -iname '. *' Lub -iname. * Albo wciągniesz. i .. znowu tak.
Domingo Ignacio Galdos
-1
ls -la | awk '$NF ~ /^\.[^.]+/  {print $NF}' | xargs rm -rf

ls -la ............. long list (all files and folders)
$NF ................ last field (file or folder name)
~   ................ Regular Expression match
/^\.[^.]+/ ......... dot followed by not dot at least once +

If the last field $NF match pattern show it and send 
it to xargs which will perform the task.
SergioAraujo
źródło
To zrywa, gdy tylko masz plik ze spacją w nazwie.
CVn