Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Mike Lewis on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Selective file deletion

Status
Not open for further replies.

SamDurai

Programmer
Aug 30, 2009
10
US
I have many files as below present in a directory.

data.20091009_0915_app.out
data.20091009_0915_db.out
data.20091009_0915_dbm.out
data.20091009_0915_lock.out
data.20091009_0930_app.out
data.20091009_0930_db.out
data.20091009_0930_dbm.out
data.20091009_0930_lock.out
data.20091009_0945_app.out
data.20091009_0945_db.out
data.20091009_0945_dbm.out
data.20091009_0945_lock.out
data.20091009_1000_app.out
data.20091009_1000_db.out
data.20091009_1000_dbm.out
data.20091009_1000_lock.out
data.20091009_1015_app.out
data.20091009_1015_db.out
data.20091009_1015_dbm.out
data.20091009_1015_lock.out
data.20091009_1030_app.out
data.20091009_1030_db.out
data.20091009_1030_dbm.out
data.20091009_1030_lock.out

I would like to retain files only with the pattern "data.*_0945*out and delete rest all the files. How can implement it ?
After cleanup I want only the following 4 files
data.20091009_0945_app.out
data.20091009_0945_db.out
data.20091009_0945_dbm.out
data.20091009_0945_lock.out
 
Here is a quick and dirty command that will remove all files except what is capured by grep, but you can filter as needed.

for file in `ls | grep -v "data.*_0945"`; do rm $file; done
 
[tt]ls|grep -v _0945_|xargs rm[/tt]

OR someting along these lines if you want to verify your actions

[tt]
mkdir _to_remove # make a trashcan
mv * _to_remove # throw everything in it
mv _to_remove/*_0945_* . # pick some files out of it
ls # verify list of current files
rm -r _to_remove # remove trashcan with contents
[/tt]


HTH,

p5wizard
 
If you are using ksh or bash with extended globbing enabled (shopt -s extglob) this should also work:

Code:
rm !(data.*_0945*)

Annihilannic.
 
-not? Hmm... I'd never seen that before. Also you left out the directory to find in. Good idea though... a more POSIX-compliant version is:

Code:
find . ! -name "data.*_0945*out" | xargs rm -f

Also beware... it will work on subdirectories if present.

Annihilannic.
 
I thought of [tt]find[/tt] also, but it will recurse into subdirs and I don't know from OP if there are (or aren't) any subdirs and - if there are - whether they may be processed in the deletion also.


HTH,

p5wizard
 
Code:
find . -maxdepth 1 -not -name "data.*_0945*out" -delete
Since a few months linux gnu-find doesn't need an explicit directory to start anymore, but uses the current.

To prevent subdirs from visits you may use maxdepth.

I don't see the advantage in usage of | xargs rm -f over -delete. Is it to impress other people with pipes? You may - if not executing rm, where -delete exists, often use -exec, -ok or -execdir from find itself,
Code:
find . -not -name "data.*_0945*out" -execdir rm -f {} \;
will itereate through subdirs, and call rm -f {} where the filename will replace the braces.

If you end the command with a plus:
Code:
find . -not -name "data.*_0945*out" -execdir rm -f {} +
the command (here: rm -f {}) is executed in parallel - maybe sometimes useful for performancereasons.

-ok instead of -execdir will ask you to confirm every command, -exec will call the file from the current directory (with its relativ path, if I remember correclty). Consult your manpage to be sure.

find --version
find (GNU findutils) 4.4.0


don't visit my homepage:
 
Piping to xargs has the same performance improvement effect as using + on the end of GNU find, but is more portable.

Annihilannic.
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top