LinuxQuestions.org
LinuxAnswers - the LQ Linux tutorial section.
Go Back   LinuxQuestions.org > Forums > Linux Forums > Linux - General
User Name
Password
Linux - General This Linux forum is for general Linux questions and discussion.
If it is Linux Related and doesn't seem to fit in any other forum then this is the place.

Notices

Reply
 
Search this Thread
Old 09-12-2011, 10:49 AM   #1
sseeg
LQ Newbie
 
Registered: Sep 2011
Posts: 4

Rep: Reputation: Disabled
Question find with -prune and -delete


Howdy!

I am trying to go through my filesystem, looking for files that end in ~ (back up files from Emacs) and delete them. The tricky bit is that I have some NFS-mounted directories in /import that sometimes go stale, so I don't want to even go into that directory at all.

I have the following, which prints out everything nicely:

Code:
find / -path /import -prune -o -regex ".*~" -type f -ctime +5 -ls
What I really want to do is repalce the -ls with -delete. But that implies the -depth option which undoes my -prune option. Help!

I thought about using something like:
Code:
find / -path /import -prune -o -regex ".*~" -type f -ctime +5 -exec rm -rf {} \;
but couldn't figure out how to protect the {} enough from odd filenames. Any ideas?

Thanks!!
Seth
 
Old 09-12-2011, 10:59 AM   #2
thesnow
Member
 
Registered: Nov 2010
Location: Minneapolis, MN
Distribution: Ubuntu, Red Hat, Mint
Posts: 113

Rep: Reputation: 25
I would use your find command to generate a list of target files (saved to a file), review the list and make any edits, then do a for loop on the list for the deletes.
 
Old 09-12-2011, 11:05 AM   #3
sseeg
LQ Newbie
 
Registered: Sep 2011
Posts: 4

Original Poster
Rep: Reputation: Disabled
Quote:
Originally Posted by thesnow View Post
I would use your find command to generate a list of target files (saved to a file), review the list and make any edits, then do a for loop on the list for the deletes.
Thanks, thesnow, but I need it to be automated (this, and similar commands need to run on 20+ servers.
 
Old 09-12-2011, 12:29 PM   #4
David the H.
Bash Guru
 
Registered: Jun 2004
Location: Osaka, Japan
Distribution: Debian sid + kde 3.5 & 4.4
Posts: 6,823

Rep: Reputation: 1946Reputation: 1946Reputation: 1946Reputation: 1946Reputation: 1946Reputation: 1946Reputation: 1946Reputation: 1946Reputation: 1946Reputation: 1946Reputation: 1946
I don't see why your second one wouldn't work. The names are all handled internally and are never subjected to shell parsing, so odd filenames shouldn't be a problem.

The other usual option is to pipe the names into xargs, using null separators to avoid shell word-splitting.

Code:
find / -path /import -prune -o -regex ".*~" -type f -ctime +5 -print0 | xargs -0 rm -f
Also the -r option to rm shouldn't be necessary, since it's only removing files.


On another note,I wonder if bracketing the the two expressions separately would keep them from affecting each other.
Code:
find / \( -path /import -prune \) -o \( -regex ".*~" -type f -ctime +5 -delete \)
I'm not going to test it myself though.
 
1 members found this post helpful.
Old 09-12-2011, 05:13 PM   #5
GazL
Senior Member
 
Registered: May 2008
Posts: 3,319

Rep: Reputation: 881Reputation: 881Reputation: 881Reputation: 881Reputation: 881Reputation: 881Reputation: 881
An alternative approach would be to use the '-xdev' option to stop find crossing mountpoints, but you'll need to explicitly list the filesystems you do want it to process (which is possibly not a bad thing to do anyway)

e.g. for /, /home, and /var (assuming you have a separate /home and /var filesystem - which I always do)
Code:
find / /home /var -xdev -regex ".*~" -type f -ctime +5
You should be able to add '-delete' to that once you're happy with it.

This approach will also prevent it needlessly traversing /proc and /sys and other filesystems that you're not interested in without having to prune them out
 
Old 09-13-2011, 08:20 AM   #6
sseeg
LQ Newbie
 
Registered: Sep 2011
Posts: 4

Original Poster
Rep: Reputation: Disabled
Smile

Quote:
Originally Posted by David the H. View Post
The other usual option is to pipe the names into xargs, using null separators to avoid shell word-splitting.

Code:
find / -path /import -prune -o -regex ".*~" -type f -ctime +5 -print0 | xargs -0 rm -f
Thank you! That is the solution that works, since xargs will protect the filenames.
 
Old 09-13-2011, 08:24 AM   #7
sseeg
LQ Newbie
 
Registered: Sep 2011
Posts: 4

Original Poster
Rep: Reputation: Disabled
Quote:
Originally Posted by GazL View Post
An alternative approach would be to use the '-xdev' option to stop find crossing mountpoints, but you'll need to explicitly list the filesystems you do want it to process (which is possibly not a bad thing to do anyway)

e.g. for /, /home, and /var (assuming you have a separate /home and /var filesystem - which I always do)
Code:
find / /home /var -xdev -regex ".*~" -type f -ctime +5
You should be able to add '-delete' to that once you're happy with it.

This approach will also prevent it needlessly traversing /proc and /sys and other filesystems that you're not interested in without having to prune them out
GazL - The -xdev is a good idea, but it doesn't work by itself. When an NFS mount goes stale (using hard mounting), any "ls" of the parent directory (or any command referencing the NFS link) will hang until the server comes back. That's why we can't go into the /imports directory at all.
 
Old 09-13-2011, 03:40 PM   #8
GazL
Senior Member
 
Registered: May 2008
Posts: 3,319

Rep: Reputation: 881Reputation: 881Reputation: 881Reputation: 881Reputation: 881Reputation: 881Reputation: 881
Ahh, ok, I'd assumed that -xdev would stop it from running stat() on the mountpoints, I guess it just stops it descending into them. Thanks for the feedback, I'll have to remember that one.


If you're using the xargs solution, you'll want to add the '-r' switch for when there aren't any matches.
 
Old 01-10-2013, 04:06 AM   #9
phrenq
LQ Newbie
 
Registered: Jan 2013
Posts: 1

Rep: Reputation: Disabled
Exclamation

Quote:
Originally Posted by David the H. View Post
On another note,I wonder if bracketing the the two expressions separately would keep them from affecting each other.
Code:
find / \( -path /import -prune \) -o \( -regex ".*~" -type f -ctime +5 -delete \)
I'm not going to test it myself though.
Just to precise, I tested it, and this is find's answer to equivalent command of
Code:
find / \( -path /import -prune \) -o \( -depth -regex ".*~" -type f -ctime +5 \):
Quote:
find: warning: you have specified the -depth option after a non-option argument (, but options are not positional (-depth affects tests specified before it as well as those specified after it). Please specify options before other arguments.
So it unfortunately doesn't do the job. Using xargs seems to be the best option.

Last edited by phrenq; 01-10-2013 at 04:10 AM. Reason: precised command used
 
  


Reply


Thread Tools Search this Thread
Search this Thread:

Advanced Search

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
[SOLVED] Using find and prune to not print path grail Linux - Newbie 2 01-10-2011 10:16 AM
Using find command with -prune and -xdev learn2bperfect Linux - Newbie 4 02-25-2009 11:22 PM
find using -prune and -size sharky Programming 4 09-24-2008 04:14 AM
Use the prune option in find command frznchckn Linux - General 1 06-06-2007 07:18 PM
How to prune more than one directory using GNU find judgex Programming 1 06-03-2006 11:50 PM


All times are GMT -5. The time now is 04:58 PM.

Main Menu
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
identi.ca: @linuxquestions
Facebook: linuxquestions Google+: linuxquestions
Open Source Consulting | Domain Registration