How to delete multiple files at once in Bash on Linux?

对着背影说爱祢 提交于 2020-07-31 06:10:30

问题


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?


回答1:


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.




回答2:


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.




回答3:


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' .




回答4:


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



回答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.




回答6:


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.




回答7:


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/*


来源:https://stackoverflow.com/questions/10516384/how-to-delete-multiple-files-at-once-in-bash-on-linux

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!