11

I'd like to run a command line:

cd ~/www/tmp/; rm -P 2*

But I get an error if there are no files starting with 2.

You would think I would want to use -f, however:

-f      Attempt to remove the files without prompting for confirmation, regardless of the file's permissions.  If the file does not exist, do not display a diagnostic message or modify the exit status to reflect an error.

And I do care about file permissions- if there's something weird going on, I'd prefer the command abort. I only want to suppress 'do not exist' errors.

I've looked at some other questions with 'rm errors', and found these two which seem (kinda) relevant:

Delete files and directories by their names. No such file or directory

But, I don't understand everything going on in the answers to this question, and don't know that I need it?

The touch hack suggested in this question:

Have rm not report when a file is missing?

Seems workable, as I don't think I mind the performance hit (but what type of performance hit would you take? - ie: is this a reasonably scalable technique, or am I just learning very bad habits?)

I'm not sure how I'd do an if-then within the command line.

Are there any other options for a simple command line cut-n-paste cleanup?

Would find -delete work better for my case? If so, why?


error in question:

rm: 2*: No such file or directory
muru
  • 72,889
user3082
  • 991
  • 2
  • 10
  • 18
  • 1
    The error is from your shell, not rm, so you'll need to say what that is. – Michael Homer Jun 26 '18 at 05:49
  • Are you using zsh as your interactive shell? Are you getting a No matches found error? – Kusalananda Jun 26 '18 at 06:07
  • 3
    @MichaelHomer No, the error is from rm. The shell merely passed on the string 2* to rm instead of expanding it to a list of files. Look at the error in question: it says that rm is complaining, not sh/bas/zsh/... – doneal24 Jun 26 '18 at 12:46

1 Answers1

13

To only call rm -P for existing regular files whose names match a pattern in a directory (but not below):

find directory -maxdepth 1 -type f -name 'pattern' -exec rm -P {} +

E.g.,

find ~/www/tmp/ -maxdepth 1 -type f -name '2*' -exec rm -P {} +

To match only non-directories, use ! -type d in place of -type f. The difference is that ! -type d would be true for a wider range of file types (symbolic links, named pipes, sockets, etc.)

Since you want to be prompted for some conditions on the files found, you should not use -delete instead of -exec rm since that works as rm -f.

Remove -maxdepth 1 to let find look in subdirectories recursively.

Kusalananda
  • 333,661
  • 3
    Though ! -type d might be closer to rm 2*, I think? – muru Jun 26 '18 at 06:14
  • So, I'd have to add -P to get that functionality?: find ~/www/tmp/ -maxdepth 1 -type f -name '2*' -exec rm -P {} + – user3082 Jun 26 '18 at 06:52
  • @user3082 Yes, I forgot that you wanted to use -P too. – Kusalananda Jun 26 '18 at 06:54
  • Thanks @muru, I actually want -type f, but didn't know how to make rm act like that - so @Kusalanada's suggestion was spot-on, and the differentiation / explanation is great for learning. – user3082 Jun 26 '18 at 07:06
  • @user3082 you'd probably have to use your shell's extended globbing (e.g., rm 2*(.) in zsh). – muru Jun 26 '18 at 07:07