Weblog entry #176 for Steve
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
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 ]
[ Send Message | View dkg's Scratchpad | View Weblogs ]
[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 ]
[ 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'
[ Parent | Reply to this comment ]
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 ]
[ 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.
[ Parent | Reply to this comment ]
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 ]
[ Parent | Reply to this comment ]
[ 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 ]
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 ]
[ Send Message | View lters's Scratchpad | View Weblogs ]
[ Parent | Reply to this comment ]
[ Parent | Reply to this comment ]
[ Parent | Reply to this comment ]
-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 ]
// Alex
[ Parent | Reply to this comment ]
[ Parent | Reply to this comment ]
[ Parent | Reply to this comment ]
[ Parent | Reply to this comment ]