Assume there is a folder that has files, symbolic links, and subdirectories as following:

files: file1, file2, file3, file4
symbolic links: link1-->file2, link2-->file3
subdirectories: dir1, dir2

I want delete file1, file3, file3, file4, link1, and link2. But leave dir1 and dir2 unchanged.

Note that, there is no one pattern such as file* can cover all files' name. The name of files above are just for example and actually their name are various.


You could use find with a type argument.

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

You can do a dry run by removing the -exex rm -f {} \; portion to see the files that would be deleted.

  • Quite enough find -maxdepth 1 -type f -delete
    – Costas
    Nov 1 '14 at 8:11
  • 1
    @Costas that's a Gnu switch only...
    – jasonwryan
    Nov 1 '14 at 8:25
  • 1
    find . -maxdepth 1 -type f -exec rm -f {} + Nov 1 '14 at 8:26
  • I edit the question to add symbolic links to be considered. Because I also find there exist some symbolic links in my folder.
    – Yulong Ao
    Nov 1 '14 at 8:38
  • @jasonwryan, -maxdepth is the GNU extension. -delete comes from BSDs. -maxdepth is also found in some other implementations. Nov 1 '14 at 18:09

Simple way is to use

$ rm ./*

Here we are not using recursive delete (-r) and so only the files (except the hidden ones) in the parent directory should get deleted.

  • I'd offer supress error output rm * 2> /dev/null
    – Costas
    Nov 1 '14 at 8:12
  • 1
    Note that it will delete symlinks, including symlinks to directories. Nov 1 '14 at 8:27
  • rm * will not delete hidden files, as * doesn't expand hidden files. Symlinks was not mentioned in question and if present it will be deleted along with and other file types leaving directories and their content. Nov 1 '14 at 9:27
  • 1
    rm * is wrong unless you can guarantee none of the file names will start with - in any context that command line will be used, which in a Q&A site answer is not the case. You want rm -- * or rm ./*. Nov 1 '14 at 9:36
  • Yes that should be a fail-safe way. Thanks for pointing it out :) Nov 1 '14 at 14:11

Using bash (and ignoring symlinks):

for file in *; do [[ -f $file ]] && rm -- "$file"; done
  • [[ -f $file ]] also returns true for symlinks to regular files (symlinks for which you can determine the type of the target is "regular"). You need either for file in ./* or rm -- "$file" here. Nov 1 '14 at 18:12
  • @StéphaneChazelas thanks: I had tested it but didn't pick that up. Updated.
    – jasonwryan
    Nov 1 '14 at 18:54

With zsh:

rm -- *(.)

removes the regular files only

rm -- *(D.)

to also include dot-files (hidden ones)

rm -- *(D^/)

removes all types of files except directories (that include symlinks to directories)

rm -- *(D^-/)

removes all types of files except directories and symlinks to directories (it would remove symlinks to directories if it can't determine the type of the target of the symlink though).

The GNU find equivalent of that latter one would be:

find . -maxdepth 1 ! -xtype d -delete
sudo mkdir a b c d e

sudo touch a/1 b/2 c/3 d/4 e/5 e/a e/b   
a  b  c  d  e  pqr  xyz

cd a/         

cd ../e/     
5 a b

cd /var/warehouse/abc/  
find . -type f ! -path "./a*" ! -path "./b*"        

sudo find . -type f ! -path "./a*" ! -path "./b*" -exec rm -f {} \;
  • 1
    This removes files in subdirectories as well. Nov 1 '14 at 8:26
  • @MichałGórny: yeah, exactly.
    – Yulong Ao
    Nov 1 '14 at 8:30
  • 1
    If you are going to remove my formatting edit, at least replace it with a similarly formatted one: you current version is unreadable...
    – jasonwryan
    Nov 1 '14 at 8:41
  • @jasonwryan : I am trying out the same
    – amolveer
    Nov 1 '14 at 8:47

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.