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


13 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/