Find and delete empty directories linux

How to delete directories based on `find` output?

How could I process all these lines with rm -fr in order to delete the directories and their content?

@SuperChafouin but will not work for paths with spaces in them (hence using -exec with quoted «<>» ).

9 Answers 9

Find can execute arguments with the -exec option for each match it finds. It is a recommended mechanism because you can handle paths with spaces/newlines and other characters in them correctly. You will have to delete the contents of the directory before you can remove the directory itself, so use -r with the rm command to achieve this.

For your example you can issue:

You can also tell find to just find directories named .svn by adding a -type d check:

find . -name ".svn" -type d -exec rm -r "<>" \; 

Warning Use rm -r with caution it deletes the folder and all its contents.

If you want to delete just empty directories as well as directories that contain only empty directories, find can do that itself with -delete and -empty :

find . -name ".svn" -type d -empty -delete 

I have seen advice to always run -type after -name in find commands, since calls to stat to get the type are expensive. I just tried it myself on a fairly large bunch of files, and it seems to be true: running find . -name ‘foo’ -type d took 19 secs, while find . -type d -name ‘foo’ took 32 secs. So about 50% longer time to run -type first.

i’ve been using this command for years, but on Mac now i get errors saying those directories do not exist. Even though it does delete them. I never saw messages before.

@chovy @clément That is because find wants to see in that folder for other matches, while it’s removing the folder at the same time. ~I don’t know yet how to fix this.~ Dirty fix: find . -name «folder-to-delete» -print0 | xargs -r0 — rm -r

@chovy @Clément I think the -depth argument fixes this: find . -depth -name «.svn» -type d -exec rm -r «<>» \;

Here is a portable still faster than the accepted answer way.

Using a + instead of a semicolon as find command terminator is optimizing the CPU usage. That can be significant if you have a lot of .svn sub-directories:

find . -name .svn -type d -exec rm -rf <> + 

Note also that you never 1 need to quote the curly braces here.

1 Unless you use the fish shell (this might have been fixed since I wrote this reply).

@ShichengGuo With the semicolon, there will be one rm command per directory found, with the + a single rm command will process all directories found (or at least a very large number of them.) I don’t get your second question, curly braces are used here.

I think @ShichengGuo means why don’t we need to quote the curly braces here (@jlliagre wrote that we never need to quote them). I can’t find a reference now, but I understand it’s because find will automatically escape the paths replaced for <>.

@gaoithe I did rollback you edit which replaced a correct statement with an incorrect one. Using + does reduce CPU usage, Using ; does not lead to a command too long error.

Читайте также:  Процессор amd для linux

Assume you are using gnu find, you can use the -delete option:

which is easier to remember.

Consider expanding your post with an explanation of the command (or documentation to back up your solution). Often one (or two) line answers are not the most illuminating.

The options order is very important, find will execute them in order so, -delete have to be the last one

A faster way to do this is:

find . -name ".svn" -type d -prune -exec rm -rf '<>' '+' 

In case you have «.svn» inside another «.svn».

On my computer when I use:

find . \( -name dirname -type d \) -exec rm -r '<>' ';' 

The directories are deleted but I get the error:

find: ‘./dirname’: No such file or directory 

My directories aren’t empty, so the -delete option won’t work for me. I found the reason for this behavior here:

  1. find takes (not necessarily) the first entry in the ./ directory. this would be e.g. dir.1/
  2. it compares it to the pattern ‘dir.?’. does it match? yes.
  3. find executes «rm -r dir.1».
  4. find tries to enter dir.1/ to find the pattern within the directory. it doesn’t know anything about the exec command.
  5. it doesn’t find dir.1/ anymore. returns ENOENT (look at the strace output)

I used this instead to work around:

rm -r `find . -name dirname -type d` 

Keep in mind that find will still try to recurse into directories named dirname, which isn’t really necessary and will take some additional time. Depending on your directory structure, you might be able to work around this with the —depth find option. In addition, if you have a directory structure like dirname/foo/dirname you will get «No such file or directory» errors from rm. To suppress the errors you can redirect stderr to /dev/null or use the -f (force) flag with rm.

Источник

How to Find and Delete Empty Directories in Linux

Many times empty directories get cluttered in the Linux file system, and it becomes a difficult task to manually search for and delete each of them. The command rmdir (remove directory) is used in Linux to delete empty folders.

The command is quite simple to use and the basic syntax is:

Here, ‘empty folder name1‘, ‘empty folder name2‘, etc. are the names of the folders including the full path. If the folders are in the same directory then, as you might already know, there is no need to write down full paths.

You can also use wildcard expressions to remove empty directories with patterns in their names. For example, to remove empty directories with the substring ‘test‘ in their name, run:

Remove Empty Directories

However, to use rmdir we always need to specify the name (or full path) of each empty directory to be removed. There is no option in rmdir to recursively look for empty directories and then remove them.

We make use of the functionalities of the find command in such cases.

Find and Remove Empty Directories in Linux

The find command is used to search for files and folders in Linux based on different parameters like filename, size, type, etc. We will use find to determine empty directories recursively and then execute rmdir to delete the found directories.

Use the argument ‘-empty’ to look for empty objects and specify ‘-type d’ to only find directories.

$ find path_of_folder_to_search -type d -empty

To find empty directories recursively in the same folder, run:

Читайте также:  Linux hdd serial number

Find Empty Directories

Now, since we already have the recursively found list of empty directories, we use the ‘-exec’ argument of the find command to run rmdir over them.

$ find . -type d -empty -exec rmdir <> \;

The placeholder <> substitutes each entry in the list of found directories and ‘\;’ signifies the end of the command to be executed.

However, even with this, it will just do a single round of search and remove directories that are empty, but it will not remove directories that become empty after the first round of deletion.

To tackle this, we simply use the ‘-delete’ option, which will repeatedly delete all empty directories till the top-level directory.

$ find . -type d -empty -delete

Find and Delete Empty Directories

This is how we can remove all empty directories recursively in Linux.

Conclusion

We learned how to use the rmdir command and find command in Linux to delete empty directories recursively. Learn more about these commands in their respective man pages:

Thanks for reading and do share your thoughts below!

Источник

How do I delete all empty directories in a directory from the command line?

Say I have a directory named foo/ . This folder includes subdirectories. How can I delete all the empty directories in one command?

5 Answers 5

find . -empty -type d -delete 

The find command is used to search for files/directories matching a particular search criteria from the specified path, in this case the current directory (hence the . ).

The -empty option holds true for any file and directory that is empty.

The -type d option holds true for the file type specified; in this case d stands for the file type directory.

The -delete option is the action to perform, and holds true for all files found in the search.

Hey Bill, I tried to post another similiar question and it wouldn’t let me because it said it was a dupe, so I was hoping you might be able to answer me here. Say I wanted to do the same thing as above but remove all directories whether they are empty or not.

The way you would remove directories, regardless of whether or not they are empty, type the following command: rm -rf . This will remove the directory, along with all its contents including files and subdirectories. The -r option means delete recursively, while the -f command means don’t prompt before deleting. If you want to be prompted before deleting a directory/file, however, replace the -f option with the -i option.

It is possible to do this by using a pipe to feed the stdout of one command (e.g. find ) into the stdin of the other (e.g. rm ), however, be very careful since it may wipe out or delete files/directories that you don’t want to delete! For further information on how to do this, see the man pages for each of these commands. To be safe, always test such things in a temporary directory before trying out on the real thing.

@joeybaruch On MacOS almost every directory you «visited» with Finder.app contains a .DS_Store hidden file, that usually stores your sorting/viewing preferences for that directory. Other apps may add other hidden files (e.g. Adobe Bridge may add a .BridgeLabelsAndRatings file), so perhaps those directories aren’t really empty. Anyways, you can remove the .DS_Store file with find . -name ‘.DS_Store’ -delete and then try again to remove the empty directories with the suggested command.

Читайте также:  Learning kali linux security testing

Источник

how can I recursively delete empty directories in my home directory? [duplicate]

I create directories very often, scattered over my home directory, and I find it very hard to locate and delete them. I want any alias/function/script to find/locate and delete all empty directories in my home directory.

This does not answer your question, but could solve the underlying problem. I often use the construct: WORK=$(mktemp -d) or cd $(mktemp -d) . Of course don’t put important files that you need to preserve in those directories. But most likely your system is already setup to automagically make those files disappear after a while.

I have my machine mount a tmpfs ram drive to the /z/ directory on start-up and do all my temporary work there.

2 Answers 2

The find command is the primary tool for recursive file system operations. Use the -type d expression to tell find you’re interested in finding directories only (and not plain files). The GNU version of find supports the -empty test, so

will print all empty directories below your current directory.

Use find ~ -… or find «$HOME» -… to base the search on your home directory (if it isn’t your current directory).

After you’ve verified that this is selecting the correct directories, use -delete to delete all matches:

$ find . -type d -empty -delete 

@Santosh: The command as it is, is meant to be run from your home directory (that’s why I added ~$ in the beginning). If you want to run it regardless of your working directory, use «$HOME» instead of . as jordanm suggested in his answer.

Consider changing the second example to . instead of ~ . If somebody copy-pastes this without noticing and only checks the output of the first this can have bad consequences.

I would add -mindepth 1 here, to prevent from deleting the starting directory itself, if it would be empty. It’s not really probable case for $HOME but if you would use this on any other directory..

You can call rmdir on every directory, since rmdir will only delete a directory if it is empty:

find "$HOME" -type d -exec rmdir <> + 2>/dev/null 

If you also want to print the directories being removed, you will need to check if they are empty:

find "$HOME" -type d -exec bash -c 'shopt -s nullglob; shopt -s dotglob; files=("$1"/*); [[ $ ]] || rmdir -v "$1"' -- <> \; 

Here is a pure bash example (version 4 or higher):

shopt -s globstar for dir in **/; do files=("$dir"/*) [[ $ ]] || rmdir -v "$dir" done 

BusyBox find doesn’t have -empty , so the -exec trick is helpful. But rather than sending errors off to /dev/null, it’s better to tell rmdir to suppress them, e.g. find . -type d -depth -exec rmdir -p —ignore-fail-on-non-empty <> \;

These commands have terrible performance since they create a new process for every directory found. When using that approach, you really should at least use something like find . | xargs -n 100 rmdir to delete them in batches. Even then, it won’t work properly because it will fail to remove early directories that will later become empty because of later empty directories’ removal. Thus you’d need to execute it several times.

@jlh No, the first command will only execute rmdir once. That’s the difference between using + and \; for terminating a command in find .

Источник

Оцените статью
Adblock
detector