Linux delete files only

Remove all files except some from a directory

There are 2 ways to read this question, and the existing answers cover both interpretations: EITHER: (a) preserve files with the specified names directly located in the target directory and — as rm -r implies — delete everything else, including subdirectories — even if they contain files with the specified names; OR: (b) traverse the entire subtree of the target directory and, in each directory, delete all files except those with the names listed.

To everyone doing this, please make a backup first. I’ve just wasted several days worth of work because I forgot to exclude .git , and not having pushed, I was unable to recover over 30 commits. Make sure you exclude everything you care about, hidden folders included. And set -maxdepth 1 if you’re dealing with directories.

20 Answers 20

find [path] -type f -not -name 'textfile.txt' -not -name 'backup.tar.gz' -delete 

If you don’t specify -type f find will also list directories, which you may not want.

Or a more general solution using the very useful combination find | xargs :

find [path] -type f -not -name 'EXPR' -print0 | xargs -0 rm -- 

for example, delete all non txt-files in the current directory:

find . -type f -not -name '*txt' -print0 | xargs -0 rm -- 

The print0 and -0 combination is needed if there are spaces in any of the filenames that should be deleted.

rm !(textfile.txt|backup.tar.gz|script.php|database.sql|info.txt) 

The extglob (Extended Pattern Matching) needs to be enabled in BASH (if it’s not enabled):

I get «syntax error near unexpected token `(‘» when I do shopt -s extglob; rm -rf !(README|LICENSE) . Any idea why?

This is the best solution for me and it works by default on my Ubuntu 12.04.4 LTS with no need for shopt

@nic, @Dennis: The syntax error suggests that something OTHER than bash was used, e.g., dash , where extglob is not supported. However, in an interactive bash shell, the command will ALSO not work as stated, though for different reasons. The short of it: execute shopt -s extglob BY ITSELF; ONCE SUCCESSFULLY ENABLED (verify with shopt extglob ), execute rm -rf !(README|LICENSE) . (While extglob is not yet enabled, !(. ) is evaluated by history expansion BEFORE the commands are executed; since this likely fails, NEITHER command is executed, and extglob is never turned on.)

@nic, @Dennis, @mklement0: I had the same issue with «syntax error near unexpected token (» when executing the command within a .sh file (#! /bin/bash) but not when I was running it in a command line interface. It turned out that in addition to the shopt -s extglob run in the command line interface, I had to rerun it inside my script file. This solved the problem for me.

Читайте также:  Все команды linux echo

find . | grep -v «excluded files criteria» | xargs rm

This will list all files in current directory, then list all those that don’t match your criteria (beware of it matching directory names) and then remove them.

Update: based on your edit, if you really want to delete everything from current directory except files you listed, this can be used:

mkdir /tmp_backup && mv textfile.txt backup.tar.gz script.php database.sql info.txt /tmp_backup/ && rm -r && mv /tmp_backup/* . && rmdir /tmp_backup 

It will create a backup directory /tmp_backup (you’ve got root privileges, right?), move files you listed to that directory, delete recursively everything in current directory (you know that you’re in the right directory, do you?), move back to current directory everything from /tmp_backup and finally, delete /tmp_backup .

I choose the backup directory to be in root, because if you’re trying to delete everything recursively from root, your system will have big problems.

Surely there are more elegant ways to do this, but this one is pretty straightforward.

Источник

How to delete files only, but keep the directory structure?

I would like to delete every file, but keep the folder structure. Is there a way? NOTE: (I’m using GNU bash 4.1.5).

How exactly do you mean to «exclude»? Are you using a command of some sort? If so please update your question to include this.

4 Answers 4

This will delete every single file, excluding directories, below the current working directory. Be extremely careful with this command.

If the version of find on your machine supports it, you can also use

@slm: I’m not sure how portable that is. I’ve added it in as a secondary option. I just realized that my edit made my answer virtually identical to yours. Sorry about that; it was not my intent.

Does the ‘<>‘ guard against spaces in files? I see you using all the time and I don’t think I’d ever seen it used before I saw you posting solutions with it.

From the GNU find manpage: «Notice that the braces are enclosed in single quote marks to protect them from interpretation as shell script punctuation.» I’m not sure when it’s necessary though. I mostly do it out of habit. The find command never sees the quotation marks. It just sees the <> marker as an argument.

I see it on the example, but the templates show this, » -exec command <> + » & this » -exec command ; «. I’ve use the \; in the past just never the ‘<>‘.

Читайте также:  Поиск дубликатов картинок linux

@slm: The templates also don’t show the escaping of the semicolon, which is generally necessary when using a shell to execute find . I think the templates are meant to show which arguments the find command needs and don’t worry about anything shell-related.

You can use the command find to locate every file but maintain the directory structure:

$ find /some/dir -type f -exec rm <> + 

Per this Unix & Linux Q&A titled: gnu find and masking the <> for some shells — which?, escaping the <> with single ticks ( ‘ ) doesn’t appear to be necessary anymore with modern day shells such as Bash.

The easy way to delete every regular file in the current directory and subdirectories recursively:

Only zsh has globbing qualifiers to match files by type. However, the rm command doesn’t work on directories, so in bash, you can use

This doesn’t work for commands other than rm though. In general, you can use find :

or if your find doesn’t support -delete :

I had similar requirement to delete files from a path and its sub directories (filtering by time ) with out deleting the directory structure .

And i have used the below format which worked for me .

find /test123/home/test_file_hip/data/nfs -mtime +6 -type f -exec rm <> \;

Syntex : find (path of file) -mtime (greater than or less than days) -type f -exec rm <> \;

-type : Mention the type of file «f» for «d» directory -exec : execute command rm : remove <> : output of find command

Note : Do test it before using it . Please feel free to correct or update if i missed anything .

Источник

Unix Command to Delete all files in a directory but preserve the directory

I am looking for a unix command to delete all files within a directory without deleting the directory itself. (note the directory does not contain subdirectories).

8 Answers 8

EDIT: added -i just in case (safety first). directory should be a full or relative path (e.g. /tmp/foo or ../trash/stuffs )

of course, you can always cd to your directory and then perform a «rm -i *» please note that the -i flag will force confirmation of each deletion, is there just for safety (nasty things will occurr if you misplace a / in your commandline and you provide a -r flag. )

I’m using rm -r * but it’s asking for a confirmation on each file deletion. To stop this it’s rm -rf * yes? Trying to delete all from current directory.

-r perform recursive deletion, -f forces deletion, assuming the rm command has not been aliased, I’d go with a rm -f *

it deletes all file inside the «yourdirectory» directory

I wouldn’t suggest to a unix newbie to use the -r switch, what if OP misplaces a / on the command line ?

Understandable but the issue is that i am clearing out spam from the remote qmail folder. There is thousands of messages to clear so I need a practical way of doing it without confirmation on each deletion.

Читайте также:  Создать хеш пароля linux

You can use find /path/to/your/folder/ -delete to delete everything within that folder.

While a wildcard rm would braek with too many files («Argument list too long»), this works no matter how many files there are.

You can also make it delete only files but preserve any subdirectories:

find /path/to/your/folder/ -type f -delete 

You could also specify any other criteria find supports to restrict the «results».

Источник

How to delete all files in a directory except some?

I need to delete all files in a directory, but exclude some of them. For example, in a directory with the files a b c . z , I need to delete all except for u and p . Is there an easy way to do this?

The answers below are a lot better, but you could just make the files to save read-only, delete all, and then change them back to their original permissions (as long as you don’t use rm -f). You’d have to know what permissions to restore and you’d have to know that nothing needed write access to them during the process. This is why the other answers are better.

17 Answers 17

What I do in those cases is to type

Then I press Ctrl + X , * to expand * into all visible file names.

Then I can just remove the two files I like to keep from the list and finally execute the command line.

@SantoshKumar: That doesn’t make sense to me. The expansion will always work, it doesn’t depend on what command you want to use afterwards.

@OliverSalzburg Sorry, the combination is little bit confusing. I think you should write like Ctrl + Shift + x + *

To rm all but u,p in bash just type:

This requires the following option to be set:

You need to shopt -s extglob , @Ashot. Also, it’s just files, not directories, which is why I’ve removed the -rf options in your command.

If you need to exclude one file of a selection of files, try this: rm !(index).html . This will delete all files ending in «.html» with the exception of «index.html».

find . ! -name u ! -name p -maxdepth 1 -type f -delete 
  • ! negates the next expression
  • -name specifies a filename
  • -maxdepth 1 will make find process the specified directory only ( find by default traverses directories)
  • -type f will process only files (and not for example directories)
  • -delete will delete the files

You can then tune the conditions looking at the man page of find

  • Keep in mind that the order of the elements of the expressions is significant (see the documentation)
  • Test your command first by using -print instead of -delete
find . ! -name u ! -name p -maxdepth 1 -type f -print 

Источник

Оцените статью
Adblock
detector