How to Delete All Subdirectories Except One in Linux Using Bash Commands


2 views

When managing directories in Linux, you might encounter situations where you need to clean up multiple subdirectories while preserving one specific directory. This is particularly common in:

  • Build systems needing to clean temporary directories
  • Log rotation scripts preserving current logs
  • Version control cleanup operations

The most straightforward approach uses a combination of find and rm commands:

find . -mindepth 1 -maxdepth 1 -type d ! -name "A" -exec rm -rf {} +

Let's analyze what each part does:

  • . - Search in current directory
  • -mindepth 1 - Don't include current directory itself
  • -maxdepth 1 - Only look at immediate subdirectories
  • -type d - Only match directories
  • ! -name "A" - Exclude directory named "A"
  • -exec rm -rf {} + - Remove matched directories recursively

Using Extended Globbing

If you have bash 4.0+ with extglob enabled:

shopt -s extglob
rm -rf !(A)

With ls and xargs

For systems with limited find capabilities:

ls -d */ | grep -v "^A/$" | xargs rm -rf

Always test commands with -print first to see what would be deleted:

find . -mindepth 1 -maxdepth 1 -type d ! -name "A" -print

For production scripts, consider adding additional safeguards:

if [ -d "A" ]; then
    find . -mindepth 1 -maxdepth 1 -type d ! -name "A" -exec rm -rf {} +
fi

Matching Multiple Exceptions

To preserve multiple directories:

find . -mindepth 1 -maxdepth 1 -type d ! -name "A" ! -name "B" -exec rm -rf {} +

Pattern Matching

Using wildcards to match directory patterns:

find . -mindepth 1 -maxdepth 1 -type d ! -name "backup_*" -exec rm -rf {} +

For directories with thousands of subdirectories, the -exec + variant is faster than -exec \; as it processes multiple files per rm invocation.


When working with Linux file systems, a common administrative task is selectively pruning directories while preserving specific ones. The scenario where we need to keep only directory "A" while removing all other subdirectories occurs frequently in:

  • Project cleanup operations
  • CI/CD pipeline maintenance
  • Server storage optimization
  • Automated deployment scripts

Here's the most efficient one-liner solution:

find . -maxdepth 1 -type d ! -name "A" ! -name "." -exec rm -rf {} +

Let's analyze each component:

find .              # Start search in current directory
-maxdepth 1         # Limit to immediate subdirectories
-type d             # Only match directories
! -name "A"         # Exclude directory named "A"
! -name "."         # Exclude current directory marker
-exec rm -rf {} +   # Execute removal command

Case 1: When dealing with spaces in directory names

find . -maxdepth 1 -type d ! -name "A" -print0 | xargs -0 rm -rf

Case 2: Using extended pattern matching (Bash 4+)

shopt -s extglob
rm -rf !(A)

Always test with -print first to verify targets:

find . -maxdepth 1 -type d ! -name "A" ! -name "." -print

For production systems, consider implementing:

  • Dry-run flags in your scripts
  • Permission verification
  • Backup mechanisms before deletion

Using ls and grep:

ls -d */ | grep -v "^A/" | xargs rm -rf

ZSH users can leverage:

rm -rf ^A/