The obvious solution produces an exit code of 1:

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

One possible solution will skip the "." and ".." directories but will only delete files whose names are longer than 3 characters:

bash$ rm -f .??*
  • Well if you're not too worried about not being able to remove . & .. then who cares? unless you're worried about ugly output in a script then I think the obvious solution is less typing that the others quite frankly.
    – hookenz
    Jul 30, 2009 at 9:31
  • Just so you know, .. and . are not files. They are references to directories. . (just a single dot) is the current directory, and .. (two dots) is a link to the directory one level up. For example, if cd /home/user, . is equal to /home/user and .. is /home/ In other words, you can't delete the . and ..(.?)
    – phuzion
    Jul 30, 2009 at 11:26
  • Thanks for the comment Matt. I often use the command in scripts with per command exit code checking (set -e). In these cases an indicative exit code is necessary. Jul 31, 2009 at 10:20
  • There is nothing inherent in . and .. that protects them from deletion with rm -rf. This is just a protection mechanism added in modern variations of rm.
    – kubanczyk
    Dec 5, 2009 at 21:46
  • And there's always rm -rf .* || true if you just want to get around the set -e behavior for that one statement. Jun 4, 2012 at 2:35

4 Answers 4

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

Should catch all cases. The .??* will only match 3+ character filenames (as explained in previous answer), the .[^.] will catch any two character entries (other than ..).

  • Thanks for the answer! Based on it I also got to the shorter version of "rm -rf .[^.]*". Aug 2, 2009 at 19:00
  • 4
    Be careful with that shorter version, it will give similar, but not identical results. It won't match names with two dots at the front (e.g. ".../" which is sometimes seen hiding rootkits, etc.) Aug 3, 2009 at 12:29
  • And be careful to make a PWD check or u loose all your settings :) Dec 11, 2013 at 9:46
  • This doesn't seem to work for zsh. Any suggestions? Feb 2, 2016 at 12:55
  • 1
    With zsh by default an empty wildcard match is treated as an error; whereas with bash it is simply passed unchanged. To make zsh behave the same way you can use the command unsetopt nomatch Feb 4, 2016 at 14:52
find -path './.*' -delete

This matches all files in the current directory which start with a . and deletes these recursively. Hidden files in non-hidden directories are not touched.

In case you really wanted to wipe everything from a directory, find -delete would suffice.

  • This will delete everything, not just those entries starting with .
    – kasperd
    Nov 10, 2015 at 10:56
  • Oh, seems I misread the question as "delete everything including hidden files"... Well, my bad.
    – Fritz
    Nov 10, 2015 at 13:01
  • @kasperd Thanks, now it should actually answer the question.
    – Fritz
    Nov 10, 2015 at 13:09

best way probably is:

  • find . -iname .* -maxdepth 1 -type f -exec rm {} \;

change rm to ls -l if you just want to see what would be deleted, to verbose the output u may want to add -v option to rm

  • -type f options tells find command to look only for files (omit dirs, links etc)
  • -maxdepth 1 tells find not to go down to subdirectories

ps. don't forget about ending '\;'

  • 1
    Careful! You mean -iname '.*' or -iname .* or else you will drag in . and .. again anyway. Jun 4, 2012 at 2:33
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.
  • This breaks the instant you have a file with whitespace in its name.
    – user
    Aug 4, 2017 at 11:42

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .