LinuxQuestions.org
Visit Jeremy's Blog.
Home Forums Tutorials Articles Register
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices


Reply
  Search this Thread
Old 08-04-2010, 04:06 AM   #1
tkmsr
Member
 
Registered: Oct 2006
Distribution: Ubuntu,Open Suse,Debian,Mac OS X
Posts: 798

Rep: Reputation: 39
script to delete selected files


I am writing a script to delete certain files
say
Code:
find / -name lighttpd
gives following output
Code:
/etc/init.d/lighttpd
/etc/lighttpd
/home/lighttpd
/opt/lighttpd-1.4.x/src/lighttpd
I do not want to delete file in home directory but rest all.
In one shell script.
So first line I am clear with but what can be the second line,
 
Old 08-04-2010, 04:21 AM   #2
zirias
Member
 
Registered: Jun 2010
Posts: 361

Rep: Reputation: 59
a for-loop and the command "dirname" will help here...
(if [ ! `dirname $i` = "/home" ]; then ...)
 
1 members found this post helpful.
Old 08-04-2010, 04:31 AM   #3
druuna
LQ Veteran
 
Registered: Sep 2003
Posts: 10,532
Blog Entries: 7

Rep: Reputation: 2405Reputation: 2405Reputation: 2405Reputation: 2405Reputation: 2405Reputation: 2405Reputation: 2405Reputation: 2405Reputation: 2405Reputation: 2405Reputation: 2405
Hi,

Is this what you are looking for:

find / -name lighttpd | grep -v "^/home/" | xargs ls -l

The grep -v part excludes all entries that contain /home/, all that is left is given to ls -l. The xargs command is needed to "feed" the ls -l command.

I used ls -l instead of rm -rf for safety (find is a powerful command). Replace ls -l with rm -rf if the output generated is what you want.

Hope this helps.

Last edited by druuna; 08-04-2010 at 04:58 AM. Reason: Excluding possible false hits (added ^ to grep command)
 
1 members found this post helpful.
Old 08-04-2010, 04:36 AM   #4
zirias
Member
 
Registered: Jun 2010
Posts: 361

Rep: Reputation: 59
druuna, when using a grep approach (the OP didn't specify whether he wanted to exclude files in subdirectories of /home, too, but let's assume he wants that), you should at least use an anchor to only match paths starting whti /home like this:
egrep -v '^/home/'
 
1 members found this post helpful.
Old 08-04-2010, 04:43 AM   #5
colucix
LQ Guru
 
Registered: Sep 2003
Location: Bologna
Distribution: CentOS 6.5 OpenSuSE 12.3
Posts: 10,509

Rep: Reputation: 1983Reputation: 1983Reputation: 1983Reputation: 1983Reputation: 1983Reputation: 1983Reputation: 1983Reputation: 1983Reputation: 1983Reputation: 1983Reputation: 1983
Excluding the unwanted directories from the search should speed up the whole process, e.g.
Code:
find / -wholename /home -prune -o -name lighttpd -exec echo rm {} \;
echo is for testing purposes.
 
2 members found this post helpful.
Old 08-04-2010, 04:50 AM   #6
tkmsr
Member
 
Registered: Oct 2006
Distribution: Ubuntu,Open Suse,Debian,Mac OS X
Posts: 798

Original Poster
Rep: Reputation: 39
Hi thanks for all the replies.I liked all the replies great.
 
Old 08-04-2010, 04:58 AM   #7
zirias
Member
 
Registered: Jun 2010
Posts: 361

Rep: Reputation: 59
For performance reasons, I'd suggest to follow colucix' idea
 
Old 08-04-2010, 05:00 AM   #8
druuna
LQ Veteran
 
Registered: Sep 2003
Posts: 10,532
Blog Entries: 7

Rep: Reputation: 2405Reputation: 2405Reputation: 2405Reputation: 2405Reputation: 2405Reputation: 2405Reputation: 2405Reputation: 2405Reputation: 2405Reputation: 2405Reputation: 2405
Quote:
Originally Posted by tkmsr View Post
Hi thanks for all the replies.I liked all the replies great.
You're welcome

colucix solution is the one to go for, less impact then the other solutions.
 
Old 08-04-2010, 05:05 AM   #9
tkmsr
Member
 
Registered: Oct 2006
Distribution: Ubuntu,Open Suse,Debian,Mac OS X
Posts: 798

Original Poster
Rep: Reputation: 39
Quote:
Originally Posted by colucix View Post
Excluding the unwanted directories from the search should speed up the whole process, e.g.
Code:
find / -wholename /home -prune -o -name lighttpd -exec echo rm {} \;
echo is for testing purposes.
I could not understand this completely.
Can you be a bit elaborate.
I tried -wholename by lighttpd
Code:
find / lighttpd /home -prune -o -name lighttpd
/
find: `lighttpd': No such file or directory
and did not used exec I am just trying to see the way you suggested to use prune

Last edited by tkmsr; 08-04-2010 at 05:09 AM.
 
Old 08-04-2010, 05:38 AM   #10
colucix
LQ Guru
 
Registered: Sep 2003
Location: Bologna
Distribution: CentOS 6.5 OpenSuSE 12.3
Posts: 10,509

Rep: Reputation: 1983Reputation: 1983Reputation: 1983Reputation: 1983Reputation: 1983Reputation: 1983Reputation: 1983Reputation: 1983Reputation: 1983Reputation: 1983Reputation: 1983
Quote:
Originally Posted by tkmsr View Post
I could not understand this completely.
Can you be a bit elaborate.
Yes, of course. The action -prune just tells find to not descend into directories. Let's look at every single step:

1. Look for a directory whose whole name is /home
Code:
$ find / -wholename /home
/home
The name is relative to the specified search path, in this case / (root). This tell us that there is (obviously) only one item whose name is /home.

2. Add -prune
Code:
$ find / -wholename /home -prune
/home
Nothing different here, because the action -prune alone is evaluated as true and the result is to print the directory name. Actually the rule here is: if the expression contains no actions other than -prune, -print is performed on all files for which the expression is true.

3. Add an alternative (logical OR)
Code:
$ find / -wholename /home -prune -o -name lighttpd -print
/etc/init.d/lighttpd
/etc/lighttpd
/opt/lighttpd-1.4.x/src/lighttpd
Note that the expression here contains at least one action other than -prune (-print), so that the rule cited above does not apply. For this reason, when find encounters /home the left-hand-side of the expression is true and the output is null now. Instead for all the other directories, the left-hand-side of the expression is false and the right-hand-side is evaluated (in this case every file whose name is lighttpd is printed out).

Note that if you omit -print (without adding any other action) the rule above is applied and -prune still has the effect to not descend into the directory, but the directory name is printed out:
Code:
$ find / -wholename /home -prune -o -name lighttpd
/etc/init.d/lighttpd
/etc/lighttpd
/home
/opt/lighttpd-1.4.x/src/lighttpd
In my previous example the action -exec prevents this behaviour.

Finally you can omit multiple directories from the search by expanding the left-hand-side of the expression with other alternatives (embedded in escaped parentheses). For example:
Code:
$ find / \( -wholename /home -o -wholename /etc \) -prune -o -name lighttpd -print
/opt/lighttpd-1.4.x/src/lighttpd
Hope this clarifies.
 
1 members found this post helpful.
Old 08-04-2010, 05:54 AM   #11
colucix
LQ Guru
 
Registered: Sep 2003
Location: Bologna
Distribution: CentOS 6.5 OpenSuSE 12.3
Posts: 10,509

Rep: Reputation: 1983Reputation: 1983Reputation: 1983Reputation: 1983Reputation: 1983Reputation: 1983Reputation: 1983Reputation: 1983Reputation: 1983Reputation: 1983Reputation: 1983
Quote:
Originally Posted by tkmsr View Post
Code:
find / lighttpd /home -prune -o -name lighttpd
/
find: `lighttpd': No such file or directory
/home
Just seen your addition. Based on the explanation in my previous post, this command tells to search into /, into /home and an item called lighttpd in the current working directory:
Code:
$ find / lighttpd /home
<omitted results for obvious reasons>
find: `lighttpd': No such file or directory
<still omitted results>
The error just tells you that a file or a directory named lighttpd does not exist in the current working dir. Also note that the files in /home will be printed twice, beacuse find first searches recursively into /, then again into /home. Specifying a multiple search path might have unpleasant side effects!

Add -prune
Code:
$ find / lighttpd /home -prune
/
find: `lighttpd': No such file or directory
/home
No other output here, since the / (root) directory is not descended. Just the two directory names listed in the (multiple) search path are printed out, since the line does not contain any action other than -prune!

Last edited by colucix; 08-04-2010 at 05:55 AM.
 
1 members found this post helpful.
Old 08-04-2010, 05:58 AM   #12
grail
LQ Guru
 
Registered: Sep 2009
Location: Perth
Distribution: Manjaro
Posts: 10,007

Rep: Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191
As usual colucix has provided the good oil along with a great explanation. I thought I would just add an extra choice as I read the original query
to mean not from my home directory, but this says nothing about what if in others, so the simple addition of $HOME works nicely
Code:
find / -wholename $HOME -prune -o -name lighttpd -exec echo rm {} \;
 
Old 08-05-2010, 01:23 AM   #13
tkmsr
Member
 
Registered: Oct 2006
Distribution: Ubuntu,Open Suse,Debian,Mac OS X
Posts: 798

Original Poster
Rep: Reputation: 39
Great thanks all.
 
Old 08-06-2010, 10:26 AM   #14
tkmsr
Member
 
Registered: Oct 2006
Distribution: Ubuntu,Open Suse,Debian,Mac OS X
Posts: 798

Original Poster
Rep: Reputation: 39
If lighttpd is a directory name also
Code:
find / -wholename /home -prune -o -name lighttpd -exec echo rm {} \;
rm /usr/local/sbin/lighttpd
rm /usr/src/lighttpd-1.4.26/src/lighttpd
rm /usr/src/lighttpd-1.4.x/src/lighttpd
rm /var/log/lighttpd
rm /var/lighttpd
rm /var/run/lighttpd
rm /var/cache/lighttpd
rm /etc/init.d/lighttpd
rm /etc/lighttpd
rm /etc/cron.daily/lighttpd
rm /etc/logrotate.d/lighttpd
I am having certain directories also with the same name how do I put it here on command line.
Also I forgot to ask the meaning of {} at the end of the command.
 
Old 08-06-2010, 10:57 AM   #15
grail
LQ Guru
 
Registered: Sep 2009
Location: Perth
Distribution: Manjaro
Posts: 10,007

Rep: Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191
{} represents the items found

rm -r will get rid of a directory and all sub-directories and files.
 
  


Reply



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 Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
I need a script to Delete Selected BackupFiles and Restore selected backup file finalwar Linux - Newbie 3 07-20-2010 02:10 AM
[SOLVED] delete selected files from sftp dina3e Linux - Newbie 4 04-07-2010 02:43 AM
How to delete selected files? thomas2004ch Linux - Newbie 8 02-10-2010 11:50 AM
need to rsync only selected files (--files-from) also need to delete files on dest. ? BrianK Linux - General 5 10-22-2009 09:52 PM
Script help - delete files older than 45 days but exclude the system files jojothedogboy Linux - Software 3 06-13-2008 03:43 PM

LinuxQuestions.org > Forums > Non-*NIX Forums > Programming

All times are GMT -5. The time now is 02:44 AM.

Main Menu
Advertisement
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
Open Source Consulting | Domain Registration