7

I have a directory containing several files ending with .pyc, which I'd like to all remove in one go. I've tried both

find . -name '*pyc' | rm

and

find . -name '*pyc' -exec rm

However, neither of these statements is in accordance with the usage (in the first case) or syntactically correct (in the second case, I get find: -exec: no terminating ";" or "+"). How can I 'pipe' the results to a 'remove' command?

Kurt Peek
  • 52,165
  • 91
  • 301
  • 526

3 Answers3

8
find . -name '*.pyc' -exec rm -- '{}' +

From man find:

  • -exec utility [argument ...] ; True if the program named utility returns a zero value as its exit status. Optional arguments may be passed to the utility. The expression must be terminated by a semicolon (;). If you invoke find from a shell you may need to quote the semicolon if the shell would otherwise treat it as a control operator. If the string {} appears anywhere in the utility name or the arguments it is replaced by the pathname of the current file. Utility will be executed from the directory from which find was executed. Utility and arguments are not subject to the further expansion of shell patterns and constructs.

  • -exec utility [argument ...] {} + Same as -exec, except that {} is replaced with as many pathnames as possible for each invocation of utility. This behaviour is similar to that of > xargs(1).

{} doesn't need to be quoted in bash, but this helps compatibility with some other extended shells.

Charles Duffy
  • 280,126
  • 43
  • 390
  • 441
3

Following Why are the backslash and semicolon required with the find command's -exec option?, I used

find . -name '*pyc' -exec rm {} \;
Kurt Peek
  • 52,165
  • 91
  • 301
  • 526
  • 1
    This runs `rm` once per file. It's *much* less efficient with a large number of files than `-exec rm -- {} +` (which runs `rm` the smallest number of times necessary to get all the files onto its command line); and without the `--` argument, it would treat a file named `-r` as an argument to `rm` rather than as something to delete (if your `find` operation weren't prefixing it with `./`, as it does here). – Charles Duffy Jul 11 '17 at 15:51
0
rm *.pyc

Why do you need the find command if they're all in the same directory? You've already found them.

Difster
  • 3,264
  • 2
  • 22
  • 32
  • This will fail if there are more filenames than can fit on a single command line (typically about 64-128kb of content on modern systems). Thus, there *is* a point to using `find`. – Charles Duffy Jul 11 '17 at 15:48
  • Also, the `.pyc` files are also in subdirectories, not just the top-level directory. – Kurt Peek Jul 11 '17 at 15:52
  • 1
    @KurtPeek, incidentally, if you had `shopt -s globstar` enabled (with bash 4.0 or newer as your shell), then `rm *.pyc **/*.pyc` would recurse into subdirectories. – Charles Duffy Jul 11 '17 at 15:53
  • @KurtPeek - You did say "a directory." – Difster Jul 11 '17 at 19:06