Delete all files and directories but certain ones using Bash
Solution 1
You may try:
rm -rf !(mysql|init)
Which is POSIX defined:
Glob patterns can also contain pattern lists. A pattern list is a sequence
of one or more patterns separated by either | or &. ... The following list
describes valid sub-patterns.
...
!(pattern-list):
Matches any string that does not match the specified pattern-list.
...
Note: Please, take time to test it first! Either create some test folder, or simply echo
the parameter substitution, as duly noted by @mnagel:
echo !(mysql|init)
Adding useful information: if the matching is not active, you may to enable/disable it by using:
shopt extglob # shows extglob status
shopt -s extglob # enables extglob
shopt -u extglob # disables extglob
Solution 2
This is usually a job for find
. Try the following command (add -rf
if you need a recursive delete):
find . -maxdepth 1 \! \( -name mysql -o -name temp \) -exec rm '{}' \;
(That is, find entries in .
but not subdirectories that are not [named mysql
or named tmp
] and call rm
on them.)
Solution 3
You can use find, ignore mysql and temp, and then rm -rf them.
find . ! -iname mysql ! -iname temp -exec rm -rf {} \;
Bobo
Recent graduate with a double major in Computer Science and Mathematics. Currently working as a Software Developer I in a financial institution.
Updated on June 03, 2022Comments
-
Bobo almost 2 years
I'm writing a script that needs to erase everything from a directory except two directories, mysql and temp.
I've tried this:
ls * | grep -v mysql | grep -v temp | xargs rm -rf
but this also keeps all the files that have mysql in their name, that i don't need. it also doesn't delete any other directories.
any ideas?
-
Bobo almost 11 yearsworks like a charm! thanks! (definitely was testing somewhere else, don't wanna break things)
-
Rubens almost 11 yearsIf this answers your question, mark the answer as accepted. It both allows others to know the question has been answered, as it means you acknowledge others effort to help you. To accept an answer, click on the tick mark, below the voting arrows.
-
mnagel almost 11 yearsfor testing use
echo
as inecho !(mysql|init)
-
Bobo almost 11 yearsthis also deletes the files inside the two folders
-
Bobo almost 11 yearsthis also deletes the files inside the two folders
-
Bobo almost 11 yearsok this works in the command line, but not in my script. Syntax error: "(" unexpected
-
Rubens almost 11 yearsI'm sure this is worth another question! Would you mind to post it? -- I sincerely do not know a solution, but I'm still searching (:
-
chrylis -cautiouslyoptimistic- almost 11 yearsNot with the
maxdepth
option. Remove the-exec rm '{}' \;
to get a list of the matching files, which won't include anything below./
. -
Motin over 9 years> ok this works in the command line, but not in my script. Syntax error: "(" unexpected In a script, you need to explicitly enable extended globbing. Put this anywhere above the line:
shopt -s extglob
See stackoverflow.com/questions/216995/… -
Rubens over 9 years@Motin Duly noted! I've added the information you pointed. Thanks for that!
-
Jon L. over 9 yearsThis returns back
.
as well, so if you're executingrm -Rf
, could potentially delete more than you intend... -
ishmael about 7 yearsAdd -mindepth 1 to avoid deleting the current directory.
-
mikewaters about 7 yearsTo not delete everything inside these folders, use
find . -maxdepth 1 ! -iname mysql ! -iname temp -exec rm -rf {} \;
, or even betterfind . -maxdepth 1 ! -iname mysql ! -iname temp -delete
-
kara deniz almost 5 yearsthis in turn won't delete anything inside other subdirectories.
-
staabm almost 5 yearsnote: this will not delete hidden directories like
.svn
or.git
or simliar