Weblog entry #176 for Steve

Deleting lots of files with find
Posted by Steve on Wed 20 Jun 2007 at 23:38
Tags:

I frequently use find to find all files matching a pattern and then delete them. The simple way of doing this is :

skx@vain:~$ find . -name '*.deb' -exec rm -f \{\} \;

The "best" way of doing this is to use xargs, such that you don't spawn one command for each file to be deleted:

skx@vain:~$ find . -name "*.deb" -print | xargs rm

(Note: Yes I'm ignoring files with spaces in their names.)

Why "best"? Because tonight, after using find for years I learned about an even better method:

skx@vain:~$ find . -name "*.deb" -delete

Did you know that find had a -delete flag? I certainly didn't ..

I'll post this here so that other people learn of it, and I don't forget it. I'd post it as an article, but I'm not sure it is justifiable.

 

Comments on this Entry

Posted by Thorsten (80.69.xx.xx) on Thu 21 Jun 2007 at 08:16
[ Send Message ]
oh nice, I also never mentioned this :)

BTW:
"info find -> Actions -> Delete Files" and also "find --help | grep delete" shows this information - but not man find. :(

7horsten

[ Parent | Reply to this comment ]

Posted by dkg (216.254.xx.xx) on Thu 21 Jun 2007 at 17:57
[ Send Message | View dkg's Scratchpad | View Weblogs ]
really? It's in my find man page on lenny:
[0 dkg@squeak ~]$ dpkg -l findutils
Desired=Unknown/Install/Remove/Purge/Hold
| Status=Not/Installed/Config-files/Unpacked/Failed-config/Half-ins talled
|/ Err?=(none)/Hold/Reinst-required/X=both-problems (Status,Err: uppercase=bad)
||/ Name           Version        Description
+++-==============-==============-=============================== =============
ii  findutils      4.2.31-1       utilities for finding files--find, xargs, an
[0 dkg@squeak ~]$ man find | grep -A3 '.-delete'
       -delete
              Delete files; true if removal succeeded.  If the removal failed,
              an error message is issued.  Use of  this  action  automatically
              turns on the ’-depth’ option.
[0 dkg@squeak ~]$ 

[ Parent | Reply to this comment ]

Posted by Steve (62.30.xx.xx) on Thu 21 Jun 2007 at 19:19
[ Send Message | View Steve's Scratchpad | View Weblogs ]

Yes I see it documented both for Sid and Etch.

It isn't documented for Sarge, but that isn't a problem because it doesn't work there:

skx@sarge:/tmp$ find . -name foo -delete
find: invalid predicate `-delete'

Steve

[ Parent | Reply to this comment ]

Posted by Excds (217.78.xx.xx) on Wed 27 Jun 2007 at 15:03
[ Send Message ]
This comment isn't related to the thread. It's more of two questions.

1: How do you get those fancy colours? I would've used it in the article I posted if I'd known how. :-/
2: When I was writing the article, I first used Textile formatting. When I tried the preview all the ">" was converted to ">", even though they were enclosed in PRE-tags. Is that a bug when posting?

And yeah also, nice tip. ;-)

/Daniel
--
Ever noticed something? Unix comes with compilers. Windows comes with
Solitaire.

[ Parent | Reply to this comment ]

Posted by Steve (80.68.xx.xx) on Wed 27 Jun 2007 at 15:37
[ Send Message | View Steve's Scratchpad | View Weblogs ]

I did mean to make a post about it, but I didn't want to get too bogged down with HTML details that 99% of people probably wouldn't care about.

The CSS magic comes from dkg who used it in his article on resizing encrypted partitions. I made some minor changes and applied it to the normal CSS stylesheet and the fancy CSS stylesheet too.

In short you need to enter something like this::

<pre class="terminal">
<span class="prompt">[0 root@monkey ~]# </span><span class="input">lvs | grep testy</span>
</pre>

There is probably some magical regexp-fu I could use to apply this automatically, but I've not spent the time thinking about it. To be honest I'd probably not implement it either; there are just too many ways in which it could go wrong ..

(I tend to always write my comments/posts in HTML; so I've not even considered the other formats. I just added those because people asked for them ..)

As for your textile issue; yes that sounds like a bug. I'll take a look at it shortly.

Steve

[ Parent | Reply to this comment ]

Posted by Thorsten (80.69.xx.xx) on Fri 22 Jun 2007 at 07:12
[ Send Message ]
you are right!
If I export LANG=C on etch the option is shown.

Yesterday I tested as user with LANG=de_DE.UTF-8 and the option delete isn´t there:

0 thorsten@uin:~
$ env | grep LANG
LANG=de_DE.UTF-8
0 thorsten@uin:~
$ man find | grep -A3 '.-delete'
Formatiere find(1) neu, bitte warten...
1 thorsten@uin:~
$ export LANG=C
0 thorsten@uin:~
$ man find | grep -A3 '.-delete'
Reformatting find(1), please wait...
       -delete
            ;   Delete files; true if remo val succeeded.  If the removal fail ed,
            ;   an  error  message &n bsp;is issued.  Use of this action& nbsp;automatically
            ;   turns on the '-depth' opti on.

so it´s a problem with my german manpage.

[ Parent | Reply to this comment ]

Posted by Nilshar (82.238.xx.xx) on Thu 21 Jun 2007 at 08:46
[ Send Message | View Weblogs ]
BSD find has -delete since years... glad it finally appeared on GNU (it's not on manpage though)

[ Parent | Reply to this comment ]

Posted by Utumno (60.248.xx.xx) on Thu 21 Jun 2007 at 09:06
[ Send Message | View Utumno's Scratchpad | View Weblogs ]

Nice to get to know that.

One remark: in the original line, you dont need to escape the '{}'.

find . -name '*.deb' -exec rm -f {} \;

works.

[ Parent | Reply to this comment ]

Posted by ajt (204.193.xx.xx) on Thu 21 Jun 2007 at 13:28
[ Send Message | View Weblogs ]
I saw the delete option in someone's blog recently - can't remember where.

I have tended to use the xargs, or even a temporary file, so I don't delete the wrong thing by accident.

--
"It's Not Magic, It's Work"
Adam

[ Parent | Reply to this comment ]

Posted by lters (69.176.xx.xx) on Thu 21 Jun 2007 at 14:37
[ Send Message | View lters's Scratchpad | View Weblogs ]
Can't someone update the man page? That should not be hard...

[ Parent | Reply to this comment ]

Posted by Anonymous (83.98.xx.xx) on Thu 9 Aug 2007 at 11:26
If it isn`t that hard.. why not do it yourself :p

[ Parent | Reply to this comment ]

Posted by impact24 (58.71.xx.xx) on Thu 21 Jun 2007 at 16:05
[ Send Message ]
Wow, makes me wonder if there are any more such "hidden" flags for find...to find!

[ Parent | Reply to this comment ]

Posted by bdf (134.184.xx.xx) on Tue 26 Jun 2007 at 14:03
[ Send Message ]

-delete implies -depth, which means that the contents of a directory is visited before the directory itself, which means that -prune cannot be honored, which means that you might delete a whole lot more than expected.

I often employ -prune to protect Subversion hidden files. Consider the following commands in an SVN working copy:


$ find . -not "(" -name .svn -type d -prune ")" -type f -print
./a.txt

You would expect that only a.txt is removed when you replace -print by -delete. However, you do not see what really gets deleted until you include -depth:


$ find . -not "(" -name .svn -type d -prune ")" -type f -print -depth
./.svn/all-wcprops
./.svn/entries
./.svn/format
./.svn/text-base/a.txt.svn-base
./a.txt

Should you forget, you end up with a broken working copy:


$ find . -not "(" -name .svn -type d -prune ")" -type f -delete
$ svn stat
svn: warning: '.' is not a working copy

This bit me recently. find should really warn when you combine -prune with (something that implies) -depth. (Or it should just use a normal traversal and make -delete imply -prune instead.)

Conclusion: it's back to xargs rm for searches that include -prune.

[ Parent | Reply to this comment ]

Posted by Anonymous (89.16.xx.xx) on Sat 21 Jul 2007 at 23:10
Whoa, I never knew there was a -delete either! How cool!
// Alex

[ Parent | Reply to this comment ]

Posted by Anonymous (90.229.xx.xx) on Thu 13 Dec 2007 at 22:41
What does the "{} \" stand for ?

[ Parent | Reply to this comment ]

Posted by Anonymous (88.134.xx.xx) on Fri 14 Dec 2007 at 15:49
xargs is not needed anymore. One can use "-exec command {} +" to achieve the same thing as with xargs, as the man-page states.

[ Parent | Reply to this comment ]

Posted by Anonymous (217.153.xx.xx) on Tue 26 Feb 2008 at 17:52
Do "-exec rm" instead of "| xargs" with many files to remove and you will see the difference. No such problem with "-delete".

[ Parent | Reply to this comment ]

User Login

Username:

Password:

[ Advanced Login ]

Register Account

Quick Site Search