37

I Use Ubuntu 18.04, 19.10

using #!/bin/bash script how to remove the directories if they are empty from far end and stop at the directory having any file/files.

say.. I have created multiple directories with the below command

mkdir -p $HOME/.local/my/sub/directories/1/2/3

lateron during the time I have created lot of files in all directories starting from the directory "my to 1/2/3".

After some time I have deleted all the files in the directories "my", "directories", "1", "2", "3". Note that directory sub is having some files..

mkdir -p option will see if there are parent directories in the command mkdir -p $HOME/.local/my/sub/directories/1/2/3 and its safe.

Question: like above is there any command to see if the directories are empty and delete from far end and stop at directory sub I mean $HOME/.local/my/sub

0

3 Answers 3

64

The reversal of the mkdir -p command would be rmdir -p. rmdir -p will remove the folder structure up till the folder is not empty. You should be able to use rmdir instead of mkdir on your command:

rmdir -p $HOME/.local/my/sub/directories/1/2/3

You can also specify wildcards like if your $HOME/.local/my/sub/ contained like directories1, directories2 and directories3 for example, it could be done as:

rmdir -p $HOME/.local/my/sub/directories*/1/2/3

or

rmdir -p $HOME/.local/my/sub/*/1/2/3

If any folder as it is removing them contains data or another folder you will receive an error message that the directory is not empty and stops.

rmdir: failed to remove directory '/home/user/.local/my/sub': Directory not empty

Hope this helps!

4
  • 10
    This would not exactly undo mkdir if you already had empty folders there before creating the folders inside. Apr 19, 2020 at 21:36
  • 3
    Don't forget the --ignore-fail-on-non-empty option if using GNU tools. Otherwise you get a complaint as you noted. I wish there were a shorter spelling of it though (like maybe -q for "quiet"). Apr 20, 2020 at 13:23
  • 1
    @WillCrawford - as a workaround for long options like that, you could configure an alias for rmdir -p --ignore-fail-on-non-empty. In bash or similar: alias rmempty="rmdir -p --ignore-fail-on-non-empty ". Or a script that wraps rmdir adding the extra options - this is more work but that way you can add your own response to --help that explains what is going on. Apr 21, 2020 at 19:48
  • 1
    @DavidSpillett I don't like adding a lot of aliases because I forget, frankly, and end up typing the long command anyway half the time. The other half, I don't want the extra option (usually I'll want an error message if rmdir fails). Apr 24, 2020 at 3:11
7

There are two ways I'd attempt this. The easy method is as follows:

# Command to return only empty directories in the current directory:
find . -type d -empty -print

Now on my version of Ubuntu, I can simply perform the following:

# Find empty files, and delete them:
find . -type d -empty -delete

Otherwise, you can create some script with a logic to count files in a directory, and delete them. Here is a starting point for counting files in sub-directories:

#!/bin/bash

for i in */ .*/ ; do 
    echo -n $i": " ; 
    (find "$i" -type f | wc -l) ; 
done
3
  • 1
    Of course, the parent directory shouldn't be deleted using these methods as it'd count the files under it, so this should be safe to run. I'd strongly recommend not running it as root, and always ensuring your pwd isn't going to damage your system. Make a few tests before hand as well! :)
    – DankyNanky
    Apr 18, 2020 at 13:55
  • No, find will delete parent directories if they become empty after deleting empty subdirs. So find -empty -type d -print and find -empty -type d -print -delete will not show the same number of directories.
    – Åsmund
    Apr 20, 2020 at 9:46
  • @Åsmund sorry, I meant more parent directories such as /home won't be deleted, if there are sub-directories.
    – DankyNanky
    Apr 25, 2020 at 3:05
0

This is closer to the reverse of mkdir -p:

$ cat deldir
#!/bin/bash
[[ $# = 0 ]] && { echo "usage: ${0##*/} DIRECTORY..." >&2; exit 1; }
rc=0
while [[ $# != 0 ]] ;do
  dir=${1%/}    # in case someone specifies DIRECTORY/ out of habit
  shift
  while true ;do
    rmdir -- "$dir" || { rc=1; break; }
    [[ $dir = */* ]] || break
    dir=${dir%/*}
  done
done
exit $rc

Example:

mkdir -p a/b/c x/y/z
deldir   a/b/c x/y/z

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.