2

CakePHP has a convention of putting files called "empty" in empty directories. I'm sure they have a reason, but it really bugs me. (Yeah, OCD, I know...)

I want a one-line linux shell command that will delete every file with the name "empty" in every descendent directory. (I suppose it would be useful to be able to specify wildcards for more general use too.)

Any ideas?

Tom Wright
  • 914
  • 3
  • 12
  • 25
  • 1
    An educated guess is that that CVS and git don't handle empty directories in their source code, so you usually touch a placeholder file and check that in. – Martin M. Jun 10 '09 at 12:33
  • @Server Horror: That makes sense - my original guess was that it would be something like "This page intentionally left blank." – Tom Wright Jun 10 '09 at 13:15

4 Answers4

14

Simplest is:

find . -name empty -type f -exec rm -f {} \;

"." starts at current directory, replace with a directory path if you want to execute it in another location.

"-type f" just makes sure it's a file.

skraggy
  • 1,723
  • 13
  • 10
  • 2
    "find . -name empty -type f -exec rm -f {} +" will call find only as often as necessary and not for each file – Martin M. Jun 10 '09 at 12:32
  • 1
    Might want to throw on a -v flag to the rm, just so the user knows what's going on, but yes, great answer – Matt Simmons Jun 10 '09 at 12:32
  • 1
    I know you meant to say "will call rm" instead of find. – Dan Carley Jun 10 '09 at 12:42
  • 4
    "find . -name empty -type f | xargs rm -f" will call rm only once – tomdeb Jun 10 '09 at 12:59
  • 3
    tomdeb> Don't throw unquoted filenames at rm! – Dan Carley Jun 10 '09 at 13:07
  • @tomdeb: not exactly it will just like the "find ... +" call rm only as often as necessary if there are more files than the maximum command line length is it will subsequently call rm with the appropriate number of options – Martin M. Jun 10 '09 at 13:14
  • 1
    Shame you can't down vote comments. :( tomdeb's answer is open to problems with files that have spaces in. "find . -name empty -type f -print0 | xargs -0 rm -f" is a slightly safer form. – David Pashley Jun 10 '09 at 13:20
3

Short Summary:

There are multiple options:

find . -name empty -type f -exec rm -f {} \;

will call rm once for every file

find . -name empty -type f -exec rm -f {} +

will call rm only as often as necessary by constructing a command line that uses the maximum length possible

find . -name empty -type f | xargs rm -f

same as above, you may (or rather will, as above - which was my approach) run into problems with filenames that contain characters that need quoting

find -name empty -type f -print0 | xargs -0 rm -f

is probably the best solution Please Upvote Dan C's comment it's his solution. It will as the earlier snippet call rm only as often as need by constructing a command line that uses the maximum lenght possible, the -0 switch means that arguments to the rm command will be separated by \0 so that escaping is done right in the shell.

On a side note about the comment to restrict by using -type f you can also restrict with -size 0 (exactly 0 bytes) I can't verify if CakePHP really adheres to that convention but just about every project I know that uses placeholder files to check empty directories into the source repositories does that.

Also as Matt Simons points out adding a -v flag might be a nice option to see some progress, however do notice that this will definitely slow down the whole process. A better approach might be to follow the process by using strace -p $pid_of_xargs (add addtional options if you want to follow child processes, afaik that is possible)

Another note i just found in the manpage:

find -name empty -type f -delete

after all find has all of that builtin :)

Martin M.
  • 6,428
  • 2
  • 24
  • 42
  • "find -name empty -type f -delete" Just check the manpage first, as older versions of 'find' didn't have the -delete option. But as long as your OS is current, you should have this option. – skraggy Jun 10 '09 at 13:46
  • since the OP asked for Linux I think it is valid (correct me but I don't know any distribution that doesn't come with the GNU tool collection) – Martin M. Jun 10 '09 at 16:03
  • Older versions of Linux had a find that didn't include "-delete" was all I was saying. Older versions that are sadly still regularly used in too many places. ;) – skraggy Jun 11 '09 at 13:07
2

A possible reason why cakePHP might do this is because some version control systems (e.g. Mercurial and Git) cannot track an empty directories.

-2

This might do:

rm -f $(find /var/www -name empty -print)

Find recurses by default.

Berzemus
  • 1,162
  • 3
  • 11
  • 19
  • Will not work correctly if there's (ugh) spaces, apostrophes, semicolons or other weird characters in the directory names. – sunny256 Jun 10 '09 at 12:35
  • 4
    Not ideal. You might produce more arguments than your shell/rm is capable of handling. But more importantly, the argument list won't be properly escaped from nasties such as spaces. If for some reason you don't use find's -exec a safe alternative would be `-name empty -type f -print0 | xargs -0 rm -f` – Dan Carley Jun 10 '09 at 12:36