129

I have this list of files on a Linux server:

abc.log.2012-03-14
abc.log.2012-03-27
abc.log.2012-03-28
abc.log.2012-03-29
abc.log.2012-03-30
abc.log.2012-04-02
abc.log.2012-04-04
abc.log.2012-04-05
abc.log.2012-04-09
abc.log.2012-04-10

I've been deleting selected log files one by one, using the command rm -rf see below:

rm -rf abc.log.2012-03-14
rm -rf abc.log.2012-03-27
rm -rf abc.log.2012-03-28

Is there another way, so that I can delete the selected files at once?

Matthias Braun
  • 32,039
  • 22
  • 142
  • 171
user1253847
  • 5,241
  • 10
  • 29
  • 28
  • 4
    And "Say GNU/Linux, not just Linux", I hear somone thundering from the back seats. – Boris Stitnicky May 09 '12 at 13:09
  • 9
    By the way, why tthe -rf ? Are these folders ? f is to force, r is for recursive. It will work if it's only a file but be warned, using -rf each time you want to delete something is very (very) (very very) dangerous. (and you should add the tag "bash" because "linux" is too wide. – Depado May 09 '12 at 14:40
  • @BorisStitnicky - I am curious as to why the `GNU` is needed? – user66001 Sep 04 '13 at 13:28
  • 2
    @user66001: For the GNU project's opinion on the matter: http://www.gnu.org/gnu/linux-and-gnu.html. I take no position on the matter, at least not here, and this is *not* the place to debate it. – Keith Thompson Sep 04 '13 at 15:42
  • 2
    @BorisStitnicky - No need to debate, was completely clueless, and that link gave me the information level I was looking for +1 – user66001 Sep 04 '13 at 16:54

7 Answers7

191

Bash supports all sorts of wildcards and expansions.

Your exact case would be handled by brace expansion, like so:

$ rm -rf abc.log.2012-03-{14,27,28}

The above would expand to a single command with all three arguments, and be equivalent to typing:

$ rm -rf abc.log.2012-03-14 abc.log.2012-03-27 abc.log.2012-03-28

It's important to note that this expansion is done by the shell, before rm is even loaded.

unwind
  • 391,730
  • 64
  • 469
  • 606
  • Don't use "rm" if you wish to restore the files in future .You can use "rm-trash" utility : https://github.com/nateshmbhat/rm-trash – Natesh bhat Nov 20 '18 at 14:28
91

Use a wildcard (*) to match multiple files.

For example, the command below will delete all files with names beginning with abc.log.2012-03-.

rm -f abc.log.2012-03-*

I'd recommend running ls abc.log.2012-03-* to list the files so that you can see what you are going to delete before running the rm command.

For more details see the Bash man page on filename expansion.

dogbane
  • 266,786
  • 75
  • 396
  • 414
50

If you want to delete all files whose names match a particular form, a wildcard (glob pattern) is the most straightforward solution. Some examples:

$ rm -f abc.log.*             # Remove them all
$ rm -f abc.log.2012*         # Remove all logs from 2012
$ rm -f abc.log.2012-0[123]*  # Remove all files from the first quarter of 2012

Regular expressions are more powerful than wildcards; you can feed the output of grep to rm -f. For example, if some of the file names start with "abc.log" and some with "ABC.log", grep lets you do a case-insensitive match:

$ rm -f $(ls | grep -i '^abc\.log\.')

This will cause problems if any of the file names contain funny characters, including spaces. Be careful.

When I do this, I run the ls | grep ... command first and check that it produces the output I want -- especially if I'm using rm -f:

$ ls | grep -i '^abc\.log\.'
(check that the list is correct)
$ rm -f $(!!)

where !! expands to the previous command. Or I can type up-arrow or Ctrl-P and edit the previous line to add the rm -f command.

This assumes you're using the bash shell. Some other shells, particularly csh and tcsh and some older sh-derived shells, may not support the $(...) syntax. You can use the equivalent backtick syntax:

$ rm -f `ls | grep -i '^abc\.log\.'`

The $(...) syntax is easier to read, and if you're really ambitious it can be nested.

Finally, if the subset of files you want to delete can't be easily expressed with a regular expression, a trick I often use is to list the files to a temporary text file, then edit it:

$ ls > list
$ vi list   # Use your favorite text editor

I can then edit the list file manually, leaving only the files I want to remove, and then:

$ rm -f $(<list)

or

$ rm -f `cat list`

(Again, this assumes none of the file names contain funny characters, particularly spaces.)

Or, when editing the list file, I can add rm -f to the beginning of each line and then:

$ . ./list

or

$ source ./list

Editing the file is also an opportunity to add quotes where necessary, for example changing rm -f foo bar to rm -f 'foo bar' .

Keith Thompson
  • 254,901
  • 44
  • 429
  • 631
13

Just use multiline selection in sublime to combine all of the files into a single line and add a space between each file name and then add rm at the beginning of the list. This is mostly useful when there isn't a pattern in the filenames you want to delete.

[$]> rm abc.log.2012-03-14 abc.log.2012-03-27 abc.log.2012-03-28 abc.log.2012-03-29 abc.log.2012-03-30 abc.log.2012-04-02 abc.log.2012-04-04 abc.log.2012-04-05 abc.log.2012-04-09 abc.log.2012-04-10
Andrew
  • 3,733
  • 1
  • 35
  • 36
  • This should be the accepted answer as it explicitly answers the posed question. It's more friendly to people who came here from Google. – ATLief Oct 31 '16 at 19:35
5

A wild card would work nicely for this, although to be safe it would be best to make the use of the wild card as minimal as possible, so something along the lines of this:

rm -rf abc.log.2012-*

Although from the looks of it, are those just single files? The recursive option should not be necessary if none of those items are directories, so best to not use that, just for safety.

Maehler
  • 6,111
  • 1
  • 41
  • 46
lacrosse1991
  • 2,972
  • 7
  • 38
  • 47
3

I am not a linux guru, but I believe you want to pipe your list of output files to xargs rm -rf. I have used something like this in the past with good results. Test on a sample directory first!

EDIT - I might have misunderstood, based on the other answers that are appearing. If you can use wildcards, great. I assumed that your original list that you displayed was generated by a program to give you your "selection", so I thought piping to xargs would be the way to go.

Dave
  • 14,618
  • 13
  • 91
  • 145
0

if you want to delete all files that belong to a directory at once. For example: your Directory name is "log" and "log" directory include abc.log.2012-03-14, abc.log.2012-03-15,... etc files. You have to be above the log directory and:

rm -rf /log/*
Liner
  • 123
  • 2
  • 12
Alican
  • 21