1

Is there a way to remove all temp files and executables under one folder AND its sub-folders?

All that I can think of is:

$rm -rf *.~

but this removes only temp files under current directory, it DOES NOT remove any other temp files under SUB-folders at all, also, it doesn't remove any executables.

I know there are similar questions which get very well answered, like this one: find specific file type from folder and its sub folder but that is a java code, I only need a unix command or a short script to do this.

Any help please? Thanks a lot!

Community
  • 1
  • 1
Fisher Coder
  • 3,278
  • 12
  • 49
  • 84

5 Answers5

3

Perl from command line; should delete if file ends with ~ or it is executable,

perl -MFile::Find -e 'find(sub{ unlink if -f and (/~\z/ or (stat)[2] & 0111) }, ".")'
mpapec
  • 50,217
  • 8
  • 67
  • 127
2

You can achieve the result with find:

find /path/to/directory \( -name '*.~' -o \( -perm /111 -a -type f \) \) -exec rm -f {} +

This will execute rm -f <path> for any <path> under (and including) /path/to/base/directory which:

  • matches the glob expression *.~
  • or which has an executable bit set (be it owner, group or world)

The above applies to the GNU version of find.

A more portable version is:

find /path/to/directory \( -name '*.~' -o \( \( -perm -01 -o -perm -010 -o -perm -0100 \) \
     -a -type f \) \) -exec rm -f {} +
isedev
  • 18,848
  • 3
  • 60
  • 59
  • What about directories? – AnonSubmitter85 Oct 07 '14 at 20:29
  • Where does the OP say he wants to delete directories? – isedev Oct 07 '14 at 20:29
  • 1
    Don't directories have execute permissions? – AnonSubmitter85 Oct 07 '14 at 20:30
  • @AnonSubmitter85 lol, very good point - updated (although `rm -f` would have simply resulted in an error message). – isedev Oct 07 '14 at 20:31
  • Hi isedev, thanks a lot for the quick response. but I've entered this command: $ find /path/to/base/directory -name '*.~' -o \( -perm /111 -a ! -type d \) -exec rm -f {} +, but it gives me this error: find: -perm: /111: illegal mode string, was my command incomplete? or anything else wrong? thanks again! – Fisher Coder Oct 07 '14 at 20:43
  • @SSun probably not using the GNU version of `find`... works for me. The more portable alternative is to replace `-perm /111` with the expression `\( -perm 01 -o -perm 010 -o -perm 0100 \)`. – isedev Oct 07 '14 at 20:46
  • @isedev do you mean like this: find /path/to/base/directory -name '*.~' -o \(\( -perm 01 -o -perm 010 -o -perm 0100 \)-a ! -type d \) -exec rm -f {} + could you give me the complete command please? I'm really new to this field. Thanks a lot! – Fisher Coder Oct 07 '14 at 20:50
  • @SSun yes, allowing for missing backslash escapes and spaces: `find /path/to/base/directory -name '*.~' -o \( \( -perm 01 -o -perm 010 -o -perm 0100 \) -a ! -type d \) -exec rm -f {} +`. – isedev Oct 07 '14 at 20:51
  • @isedev OK, I tried your command again, but it gives me this error: find: -o: no expression before -o, did I miss anything? Thanks. – Fisher Coder Oct 07 '14 at 20:56
  • If you have GNU find in the first place (or BSD find), use `-delete` instead of `-exec rm`. [It goes to some trouble to avoid a clusterfsck of potential security, correctness, and performance problems.](https://www.gnu.org/software/findutils/manual/html_node/find_html/Deleting-Files.html) – zwol Oct 07 '14 at 20:57
  • @isedev so if i'm already in the current directory, should it be like: find ./ -name '*.~' -o \( \( -perm 01 -o -perm 010 -o -perm 0100 \) -a ! -type d \) -exec rm -f {} + – Fisher Coder Oct 07 '14 at 21:01
  • 1
    very true, updated to test for files (as opposed to not directories) – isedev Oct 07 '14 at 21:05
  • @isedev OK, i've tried exactly this command:find ./ -name '*.~' -o ( ( -perm 01 -o -perm 010 -o -perm 0100 ) -a ! -type d ) -exec rm -f {} +, but I got this error: -bash: syntax error near unexpected token `(', any please please? – Fisher Coder Oct 07 '14 at 21:16
  • @isedev Got it. I've escaped them now. This is literally the command I used: find ./ -name '*.~' -o \( \( -perm 01 -o -perm 010 -o -perm 0100 \) -a ! -type d \) -exec rm -f {} +, but still it doesn't seem that either temp files or executables are removed. I'm confused. Oops, it seems that StackOverflow strips off those '\'. But anyway, I've added '\' as you said, it still doesn't seem to work though. – Fisher Coder Oct 07 '14 at 21:24
  • @isedev This is super cool! I think I'm very close. It removed all executables and all temp files, but some default executables, I mean those when I use g++ code.cpp to compile, it gives me an executable called "a.out", right, all of these a.out are still there, how can we remove these then? – Fisher Coder Oct 07 '14 at 21:39
  • @SSun this must be my worst ever answer... final update (`-` before the octal modes). – isedev Oct 07 '14 at 21:47
  • 1
    Now finally is ok - **so removed my downvote**... Strange, you commented nearly all other answers as bad (and probably downvoted them too) but your answer was the worst one (dangerous!) and you managed them only after tens of comments... feel really good? :) – kobame Oct 07 '14 at 22:07
  • @kobame two comments to that: one, I quote "this must be my worst ever answer"; two: I only downvoted answers that didn't include the "executables" part - in fact, I upvoted the Perl one-liner. Now tell me, feel really fair? – isedev Oct 07 '14 at 22:09
0
find . -name "*~" -exec rm {} \;

or whatever pattern is needed to match the tmp files.

seacoder
  • 514
  • 5
  • 11
  • 1
    `find . -name "*~" -delete` – ikegami Oct 07 '14 at 20:28
  • what about executable files? – isedev Oct 07 '14 at 20:28
  • Unless you have a specific need to fork a separate command for every object found, use `-exec rm {} +`. This form collects multiple arguments for execution, greatly reducing the number of processes spawned. – JRFerguson Oct 07 '14 at 20:31
  • @JRFerguson, Note that `-exec $command {} +` is a GNU extension. (I don't know about `-delete`.) – ikegami Oct 07 '14 at 20:32
  • @ikegami Not necessarily. HP-UX and Mac OS X (as two examples of branded UNIX) have this (the `+` terminator to `find`). – JRFerguson Oct 07 '14 at 20:37
  • @JRFerguson, Even if others have adopted the extension, it's still not standard. It won't work everywhere. – ikegami Oct 07 '14 at 20:45
  • Hi seacoder, I've tried your command, but it gives me this error: find: -exec: no terminating ";" or "+" any more help please? – Fisher Coder Oct 07 '14 at 20:48
  • @SSun, did you include the trailing `\;` ? That is required when you're using the -exec syntax. – seacoder Oct 07 '14 at 20:52
  • @seacoder Yes, I have, but then it entered some mode starting with "<", is this indicating that I should give some extra commands or symbols? Thanks. – Fisher Coder Oct 07 '14 at 21:13
  • @ikegami `-exec ... {} +` is [posix](http://pubs.opengroup.org/onlinepubs/009604599/utilities/find.html), though it may not be present in very old implementations. – Reinstate Monica Please Oct 07 '14 at 22:02
  • @BroSlow, Old? I've had users on SO complain that their system didn't support `+`. Not all current systems support it. – ikegami Oct 08 '14 at 02:16
  • @ikegami There are definitely older versions which don't support it. But I think most of the time people claim not to have `+`, they are simply misusing it (i.e. omit `{}` or don't have it directly preceding the `+`). It's been in the `posix` standard since at least 2004, and the modern versions of `gnu`, `freebsd`, and `solaris` `find` all correctly support it. – Reinstate Monica Please Oct 08 '14 at 02:40
  • @BroSlow, you obviously don't know how many people still use Perl 5.8! Your definition of modern is unrealistic or what you consider modern is irrelevant. – ikegami Oct 08 '14 at 03:23
  • @ikegami This seems like a pointless argument. It simply is not a `GNU extension` and it is `standard` (complies with the `posix standard`). It also happens to be supported in the newest version of every major implementation of `find` (rephrased since you don't like the word `modern`) – Reinstate Monica Please Oct 08 '14 at 04:43
  • @BroSlow, Re "It simply is not a GNU extension", Stil as irrelevant as it was before. Re "It also happens to be supported in the newest version of every major", Still as irrelevant as it was before. I don't know why you're repeating these irrelevant arguments. The `-exec $command {} +` extension is simply not available on commonly used machines. If it's available on the machine the OP uses, fine, but I'm letting him know his solution isn't portable. Nothing you've said contradicts that, so your comments seem to have indeed been pointless. Would you mind getting rid of this spam? – ikegami Oct 08 '14 at 13:33
0

If you want to use Perl to do it, use a specific module like File::Remove

Miguel Prz
  • 13,718
  • 29
  • 42
  • 3
    File::Remove doesn't give the option to search based on permissions. You'd actually use File::Find::Rule or some such module in combination with `unlink`. – ikegami Oct 07 '14 at 20:47
0

This should do the job

find -type f -name "*~" -print0 | xargs -r -0 rm
Vytenis Bivainis
  • 2,308
  • 21
  • 28