4

For instance, I want to remove all the files in a directory except for the .tar file from whence they came. I could do something like:

find . -maxdepth 0 | grep -v '.tar$' | xargs rm -f

but is there a way to do is just using rm and shell pattern matching? Feel free to specify it using bash or other commonly available shells, or with extended options, if it can't be done with vanilla sh.

I found a similar question about avoiding directories and subdirectories with find, but not with shell patterns.

4 Answers 4

9

You can do it with extended globbing.

shopt -s extglob

then

rm !(file.tar)

This works in bash 3.2.39 at a minimum

6
  • This is the only answer so far that addresses the question with an answer. Thanks Cian... Jul 16, 2009 at 19:16
  • Is that recursive? When I run a similar command with ls it appears to be. If so, um, be very careful.
    – Telemachus
    Jul 16, 2009 at 19:44
  • @telemachus doesn't appear to be when I try it. It may depend on whether you have globstar turned on though.
    – Cian
    Jul 16, 2009 at 19:53
  • Telemachus: I don't think its recursive, it would just include directories as well. ls expands directories u.nless you use the -d switch Jul 16, 2009 at 19:55
  • @Kyle: facepalm. I'm an idiot and clearly am not thinking very quickly. Thanks, that was it.
    – Telemachus
    Jul 16, 2009 at 20:04
0

I don't think what you want to achieve is possible.

You could however simplify the command you have:

find . -maxdepth 0 -not -name '*.tar' -exec rm -f {} +
1
  • Possible, but if you get it slightly wrong, look out. I wouldn't really recommend it, though I know you're just trying to answer the OP's request.
    – Telemachus
    Jul 16, 2009 at 19:01
0

Try this perhaps

find . -maxdepth 0 \! -name '*.tar' -exec echo rm -f {} \;

Remove the echo preceding the rm if it looks right.

Yes, but is there a shell pattern?

I don't think so. At least not in the versions of bash I am familiar with. From the other answers it appears that newer versions may be more functional.

2
  • Wildcard on the end of tar doesn't match the original regex anchor. I presume the OP was using egrep.
    – Dan Carley
    Jul 16, 2009 at 18:54
  • You can do it with extglobbing in bash.
    – Cian
    Jul 16, 2009 at 19:10
0

Edit:

Read the question to fast... But in to continue with my post anyways... :-) If you want to delete all files but tar files recursively with zsh:

rm -rf **/^*.tar(.)

Non-Recursive:

rm -rf ^*.tar(.)

The new bash 4.0 and and zsh support recursive globbing. To enable it in bash use:

shopt -s globstar

It works like:

 rm -rf **/*.tar.gz
4
  • Wow. That gives me all kinds of fear :D
    – Dan Carley
    Jul 16, 2009 at 19:05
  • Um, yes, that doesn't seem like a good idea at all.
    – Telemachus
    Jul 16, 2009 at 19:47
  • Why not, just use it with echo first to make sure You don't delete the wrong stuff... Jul 16, 2009 at 19:53
  • Use it with echo first is always good advice, but I suppose I worry a lot about that one time when you're going too quickly and forget echo. **/ makes me nervous for destructive commands.
    – Telemachus
    Jul 16, 2009 at 20:06

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .