Delete all but one file linux

How to remove all but a few selected files in a directory?

I want to remove all files in a directory except some through a shell script. The name of files will be passed as command line argument and number of arguments may vary. Suppose the directory has these 5 files:

I want to remove two files from it through a shell script using file name. Also, the number of files may vary.

4 Answers 4

There are several ways this could be done, but the one that’s most robust and highest performance with large directories is probably to construct a find command.

#!/usr/bin/env bash # first argument is the directory name to search in dir=$1; shift # subsequent arguments are filenames to absolve from deletion find_args=( ) for name; do find_args+=( -name "$name" -prune -o ) done if [[ $dry_run ]]; then exec find "$dir" -mindepth 1 -maxdepth 1 "$" -print else exec find "$dir" -mindepth 1 -maxdepth 1 "$" -exec rm -f -- '<>' + fi 

Thereafter, to list files which would be deleted (if the above is in a script named delete-except ):

dry_run=1 delete-except /path/to/dir 1.txt 2.txt 

or, to actually delete those files:

delete-except /path/to/dir 1.txt 2.txt 

A simple, straightforward way could be using the GLOBIGNORE variable.

GLOBIGNORE is a colon-separated list of patterns defining the set of filenames to be ignored by pathname expansion. If a filename matched by a pathname expansion pattern also matches one of the patterns in GLOBIGNORE, it is removed from the list of matches.

Thus, the solution is to iterate through the command line args, appending file names to the list. Then call rm *. Don’t forget to unset GLOBIGNORE var at the end.

#!/bin/bash for arg in "$@" do if [ $arg = $1 ] then GLOBIGNORE=$arg else GLOBIGNORE=$:$arg fi done rm * unset GLOBIGNORE 

*In case you had set GLOBIGNORE before, you can just store the val in a tmp var then reset it at the end.

Источник

In Linux terminal, how to delete all files in a directory except one or two

In a Linux terminal, how to delete all files from a folder except one or two? For example. I have 100 image files in a directory and one .txt file. I want to delete all files except that .txt file.

You’d better show some pattern of how the exceptions should look like. Otherwise we will be able just to give a very general answer.

5 Answers 5

From within the directory, list the files, filter out all not containing ‘file-to-keep’, and remove all files left on the list.

ls | grep -v 'file-to-keep' | xargs rm 

To avoid issues with spaces in filenames (remember to never use spaces in filenames), use find and -0 option.

find 'path' -maxdepth 1 -not -name 'file-to-keep' -print0 | xargs -0 rm 

Or mixing both, use grep option -z to manage the -print0 names from find

I tried this command as sudo ls directory/directory/directory1/ | grep -v ‘readme.txt’ | xargs rm but didn’t work. I have to run this command on many directories. Suppose I directory has siblings directory2, directory3 .

Читайте также:  Linux смена сетевой карты

@Bilal For the command starting with ls , yes, it will do the job in the current directory. If you use the find command, then you can list as many directories as you want as ‘path’ .

In option 1, grep needs to have —line-regexp argument here, b/c otherwise /bin/w will match /bin/which .

In general, using an inverted pattern search with grep should do the job. As you didn’t define any pattern, I’d just give you a general code example:

ls -1 | grep -v 'name_of_file_to_keep.txt' | xargs rm -f 

The ls -1 lists one file per line, so that grep can search line by line. grep -v is the inverted flag. So any pattern matched will NOT be deleted.

For multiple files, you may use egrep:

ls -1 | grep -E -v 'not_file1.txt|not_file2.txt' | xargs rm -f 

Update after question was updated: I assume you are willing to delete all files except files in the current folder that do not end with .txt . So this should work too:

find . -maxdepth 1 -type f -not -name "*.txt" -exec rm -f <> \; 

Источник

How to delete all but one of the files in a directory

delete Linux files

Sometimes you need remove almost all files from a directory, but you want to keep one or some of them. When there are large numbers of them, going one by one is a tedious task. It is not the best option, there are ways to make the work in Linux much easier and that you can eliminate all the ones you need at once.

For example, you may want to remove only those that start with a certain name, or those that have a specific extension, etc. All that is possibleIn fact, on other occasions I have already shown similar tutorials in LxA. Here you can follow the tutorial step by step and in a simple way to be able to delete all those files you want, except what you want to save.

And the best thing is that you will not need to install any program, it can be done easily with commands like rm and find. That is, programs that are already pre-installed on any Linux distro. And of course, the method will be based on finding patterns and using those matches to remove only what you want.

Well, in order to eliminate there several alternatives, What are they…

Remove files from a directory with rm

Well, in order to use the rm command To eliminate what you feel like, you have to know before some ways to identify patterns:

  • * (list of patterns) — matches zero or more occurrences of the specified patterns
  • ? (list of patterns) — matches zero or one occurrence of the specified patterns
  • + (pattern list) — matches one or more occurrences of the specified patterns
  • @ (pattern list) — matches one of the specified patterns
  • ! (pattern list) — matches anything except one of the given patterns

To withdraw from your enable extglob In order to use them, you have to first execute the following command:

eye! I don’t specify it, but it is assumed that you have permissions to do these operations, and that you are inside that directory when you execute the rm command. Be careful with this, because if you run it in another path, you may end up deleting files that you do not want. That is, before executing these commands, make sure that you have entered the directory you want with cd.

Читайте также:  Обновление линукс командная строка

Now you can use rm to remove whatever you want. For example, delete all files from a directory except those that match the name «Lxa»:

You can also specify two or more names that you don’t want to delete. For example, to avoid removing «lxa» and «desdelinux»:

You can delete all files, minus those with extension .mp3. For example:

At the end, you can go back to disable extglob:

Remove files from a directory with find

Another alternative to rm is use find to remove whatever you fancy. You can use a pipe and xargs with rm, or use the -delete option to find. That is, the generic syntax would be:

find /directory/ -type f -not -name 'PATRÓN' -delete find /directory/ -type f -not -name 'PATRÓN' -print0 | xargs -0 -I <> rm [opciones] <>

For example, imagine you want delete all files in a directory except those with the extension .jpg, you could use one of these two commands, since they both get the same result:

find . -type f -not -name '*.jpg'-delete find . -type f -not -name '*.jpg' -print0 | xargs -0 -I <> rm -v <>

Instead, if you wanted add some extra pattern, you could too. For example, suppose you don’t want to remove either the .pdf or .odt from a directory:

find . -type f -not \(-name '*pdf' -or -name '*odt' \) -delete

Of course, you could do the same with | and xargs as in the previous example. By the way, we have used -not to deny, but you can remove that to make it positive, that is, to remove the matching patterns and not exclude them.

Delete files from a directory using the GLOBIGNORE variable

Finally, there is Another alternative to find and rm, and it’s using an environment variable to point to the files you want to remove or exclude. For example, imagine you want to delete all the files in a directory called Downloads, saving the .pdf, .mp3 and .mp4 files. In that case, you could do the following:

cd Descargas GLOBIGNORE=*.pdf:*.mp4:.*mp3 rm -v * unset GLOBIGNORE

The content of the article adheres to our principles of editorial ethics. To report an error click here.

Full path to article: Linux Addicts » GNU / Linux » System Administration » How to delete all but one of the files in a directory

Источник

Remove all files/directories except for one file

I have a directory containing a large number of files. I want to delete all files except for file.txt . How do I do this? There are too many files to remove the unwanted ones individually and their names are too diverse to use * to remove them all except this one file. Someone suggested using

Thanks, and yes I was looking for a one-line solution. It’s too time consuming to keep moving files around as I have to do this quite often.

8 Answers 8

find . ! -name 'file.txt' -type f -exec rm -f <> + 

will remove all regular files (recursively, including hidden ones) except file.txt . To remove directories, change -type f to -type d and add -r option to rm .

Читайте также:  Alt linux control center

In bash , to use rm — !(file.txt) , you must enable extglob:

$ shopt -s extglob $ rm -- !(file.txt) 

(or calling bash -O extglob )

Note that extglob only works in bash and Korn shell family. And using rm — !(file.txt) can cause an Argument list too long error.

In zsh , you can use ^ to negate pattern with extendedglob enabled:

$ setopt extendedglob $ rm -- ^file.txt 

or using the same syntax with ksh and bash with options ksh_glob and no_bare_glob_qual enabled.

Specifying the directory is good practice (fullpath in this case? or maybe add a warning here that this command deletes every file starting from the current working directory ?). I also usually write any example with rm as echo rm instead, and ask people to only take out the echo when they are really sure it will do what they want. Other than that, +1 for the thorough answer

@Meysam — see my answer for a solution that will handle a list of files. Else with Gnouc’s find solution you can do ! \( -name one_file -o -name two_file \) and so on.

Another take in a different direction (iff there are no spaces in file names)

ls | grep -xv "file.txt" | xargs rm 

or (works even if there are spaces in file names)

ls | grep -xv "file.txt" | parallel rm 
 -v, --invert-match Invert the sense of matching, to select non-matching lines. (-v is specified by POSIX) -x, --line-regexp Select only those matches that exactly match the whole line. For a regular expression pattern, this is like parenthesizing the pattern and then surrounding it with ^ and $. 

Without the -x we’d keep my-file.txt as well.

Ciao @Matteo, it works for files with spaces too, but you need to surround the grep-pattern by quotes, e.g. ls | grep -v «a file with spaces.bin» | xargs rm . This is normal grep syntax.

@Sebastian The problem is not the grep but rm . rm will get a list of space separated arguments. Try touch ‘a b’; touch ‘c d’; ls | grep -v ‘a b’ | xargs rm : you will get rm: c: No such file or directory and rm: d: No such file or directory

It’s not only spaces, it’s all blanks and newlines, but also quoting characters (single, double quotes and backslash) and filenames starting with — .

This worked for me ls -Q | grep -v file.txt | xargs rm -fr . -Q switch is «enclose entry names in double quotes»

Maintain a copy, delete everything, restore copy:

But that requires a shell that supports here-strings.

Isn’t more efficient to move it to another directory and move it back? We don’t need to deal with the content of the file, only with its path.

@Derek — it’s really not that crazy. POSIX requires that a shell redirect its input to the command you specify when it encounters a here-document. The command-substitution has to complete before anything else happens. Most shells use temp-files for here-docs — some pipes. Either way tar -c completes and the shell stashes its output before rm runs. Because rm ignores stdin its left hanging for tar -x when rm finishes — and the shell can divest itself of the copy it saved of your file(s). Here-docs can be used like aimed pipes a lot of the time.

Источник

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