Here is the situation.
I have a directory which contains many files with different extensions. I want to delete all files except one with a specific name.
This could be easily done using the GUI by selecting all and pressing ctrl and deselecting the file in question.
That is exactly what I want to, but how can I do it from the command line?
For example: dirA contains the following files:
a.txt b.txt c.php d.html a.db b.db e.html I want to delete all files keeping only the file named a.txt.
5 Answers
I've come with this easy simple great command:
rm !(a.txt) you can use ! as a negation
Test the glob with echo first i.e.
echo !(a.txt) If it doesn't work, for bash you may need to enable this with
shopt -s extglob If you wanted to keep both a.txt and b.txt, you can use !(a.txt|b.txt) or !([ab].txt).
Edit:
to make rm working recursively just add -r like
rm -r !(a.txt) and also, it is working with folder. just need to change the name to the dir name, such as for a_dir
rm -r !(a_dir) 10You can try this command:
find . \! -name 'a.txt' -delete But you need be careful because find command is recursive.
1You can do this in terminal:
cd dirA export GLOBIGNORE=a.txt rm * export GLOBIGNORE= 1Use find and xargs
find folder -type f -not -name 'a.txt' -print0 | xargs -0 rm To exclude multiple things:
find folder -type f -not -name 'a.txt' -not -name 'b.txt' -print0 | xargs -0 rm This also works with wildcards:
find folder -type f -not -name '*.png' -not -name 'b.txt' -print0 | xargs -0 rm To search in the current folder, use . in place of 'folder'.
You can use the command :
find ! -name 'a.txt' -type f -exec rm -f {} + This will look for files (-type f) in the current directory except for file a.txt (! -name 'a.txt) and then will remove them (-exec rm -f {} +)