Delete all files except files with the extension pdf in a directory
cd <the directory you want>
find . -type f ! -iname "*.pdf" -delete
- The first command will take you to the directory in which you want to delete your files
- The second command will delete all files except with those ending with
.pdf
in filename
For example, if there is a directory called temp
in your home folder:
cd ~/temp
then delete files:
find . -type f ! -iname "*.pdf" -delete
This will delete all files except xyz.pdf
.
You can combine these two commands to:
find ~/temp -type f ! -iname "*.pdf" -delete
.
is the current directory. !
means to take all files except the ones with .pdf
at the end. -type f
selects only files, not directories. -delete
means to delete it.
NOTE: this command will delete all files (except pdf files but including hidden files) in current directory as well as in all sub-directories. !
must come before -name
. simply -name
will include only .pdf
, while -iname
will include both .pdf
and .PDF
To delete only in current directory and not in sub-directories add -maxdepth 1
:
find . -maxdepth 1 -type f ! -iname "*.pdf" -delete
With bash
's extended shell globbing, you could remove any files with extensions other than .pdf
using
rm -- *.!(pdf)
As noted by @pts, the --
characters indicate the end of any command options, make the command safe in the rare case of files whose names start with a -
character.
If you want to delete files without any extension as well as those with extensions other than .pdf
, then as pointed out by @DennisWilliamson you could use
rm -- !(*.pdf)
Extended globbing should be enabled by default, but if not you can do so using
shopt -s extglob
Especially if you intend to use this inside a script, it's important to note that if the expression doesn't match anything (i.e. if there are no non-pdf files in the directory), then by default the glob will be passed unexpanded to the rm
command, resulting in an error like
rm: cannot remove `*.!(pdf)': No such file or directory
You can modify this default behaviour using the nullglob
shell option, however that has its own issue. For a more thorough discussion see NullGlob - Greg's Wiki
Delete to trash:
$ cd <the directory you want>
$ gvfs-trash !(*.pdf)
Or via mv
command (but in this way you cannot restore it from Trash since it doesn't record .trashinfo information, so this means you moved your files to a destination where it is as following).
mv !(*.pdf) ~/.local/share/Trash/files
The easiest approach: Create another directory somewhere (if you're only deleting in one directory, not recursively, it can even be a subdirectory); move all the .pdf's there; delete everything else; move the pdf's back; delete the intermediate directory.
Quick, easy, you can see exactly what you're doing. Just make sure the intermediate directory is on the same device as the directory you're cleaning up so that moves are renames, not copies!
Use bash's GLOBIGNORE:
GLOBIGNORE=x.pdf:a.pdf
rm *
unset GLOBIGNORE
From bash's man page:
GLOBIGNORE: A colon-separated list of patterns defining the set of filenames to be ignored by pathname expansion.
A quick test:
mkdir /tmp/foooooo
cd /tmp/foooooo
touch x.pdf y.zip z.mp3 a.pdf
GLOBIGNORE=x.pdf:a.pdf
ls -1 *
Output:
y.zip z.mp3