7

I want to remove certain files using find and -exec. But unlikely bash tells me, that I'm "missing" some argument.

find . -name *.png -exec rm {} /;

what do I miss?

same "missing argument" return for my attempt to rename some files:

find . -name ic_launcher.png -exec mv {} other_name.png /;

Can somebody tell me, what bash does miss, and why this command isn't successful?

Rafael T
  • 815
  • 3
  • 11
  • 16
  • 10
    Are you really putting `/;` at the end? If so, try `\;` instead. – D_Bye Jul 23 '12 at 09:32
  • 7
    By the way `find` has `-delete` option. There is no need in `-exec rm {} \;`. – rush Jul 23 '12 at 09:39
  • @D_Bye yeah, it works. If you could explain WHY I have to take a backslash instead of a slash I'll accept this – Rafael T Jul 23 '12 at 09:39
  • @rush never mentioned `-delete`. But this wouldn't work for my `mv` – Rafael T Jul 23 '12 at 09:42
  • 3
    Backslash and slash are not the same thing at all. Backslashes lean backwards: `\\ `, Forward slashes, or just slashes, lean forwards: `/`. In Unix, slashes are generally path separators, while backslashes are generally used for quoting / escaping. – jw013 Jul 23 '12 at 12:19
  • @jw013 shure, but then I could not understand, why the manual from `find` (and I guess its usually used under unix) suggests the `slash` or `path-separator` `/` to quote out the `;` instead of the `backslash` \ – Rafael T Jul 23 '12 at 12:33
  • 1
    @jw013 sorry about that! I was actually misreading it, most likely because I found so many examples that use the slash instead of the backslash. In fact the manpage is right! – Rafael T Jul 23 '12 at 12:39
  • 4
    Wherever you found those examples that used the wrong slash must not be a very good resource. I would recommend not going there for examples anymore. – jw013 Jul 23 '12 at 12:44
  • Rafael T: If you refer to MS-DOS and Windows, which use backslashes instead of slashes, please note, that UNIX is the older one, so if somebody is using something `instead`, it is the other way round. – user unknown Jul 23 '12 at 14:45

2 Answers2

17

The semicolon at the end needs to be quoted or escaped so that it is passed to find instead of being interpreted by the shell.

find . -name ic_launcher.png -exec mv '{}' other_name.png ';'

or

find . -name ic_launcher.png -exec mv '{}' other_name.png \;

should do what you're trying to do.

killermist
  • 1,591
  • 13
  • 24
Wojtek
  • 2,290
  • 2
  • 17
  • 24
  • 2
    That's because the shell might want to expand `{}` and interpret `;` as a command separator. – Wojtek Jul 23 '12 at 09:48
  • 1
    It's almost never necessary to quote `{}`. There was actually an entire question about that, but I can't find it because the site can't search for `{}`. The issue is the `/;` typo in the original question. – jw013 Jul 23 '12 at 12:17
  • 4
    Found it: [modern shells don't require quoting `{}`](http://unix.stackexchange.com/q/8647/9537). – jw013 Jul 23 '12 at 12:28
  • @jw013 That is a very fair point. I guess I usually tend to go for something that will definitely work. And after having experienced issues with no quoting, I usually quote the braces. Possibly a bit too much for my own good. – Wojtek Jul 23 '12 at 15:19
  • Yup, no harm in over-quoting. It's definitely better to err that way than the other way, but leaving out redundant quotes does save some keystrokes :). Normally I don't point out redundant quotes but in this case I just wanted to make sure the questioner understood where the real issue was, i.e. the misquoted `;` character. – jw013 Jul 23 '12 at 17:41
-4

use Pipe like the example below:

find . -name 'spam-*' | xargs rm

WAEL
  • 1,509
  • 4
  • 11
  • 16
  • that is a workaround to do what I which, but no answer on what I miss. I will use your solution for now, but I'd still like to know what I miss on the find command – Rafael T Jul 23 '12 at 09:38
  • Are you quoting the * wildcard? `find . -name "*.png"` will find all png files in or below the current dir, without those double quotes the _shell_ will expand the * so you'll find all png files with the same name as one in the current dir - probably not what you meant. –  Jul 23 '12 at 13:29
  • 3
    If you use xargs in combination with find, use -print0 etc. to sanitize against blanks etc. in filenames, so in general it is much more easy to use -exec instead, or, for `rm`, just `-delete`. – user unknown Jul 23 '12 at 14:49
  • 2
    While this may help to do what the OP is trying to do, it does not at all answer the question that was asked. – killermist Jul 23 '12 at 19:48