Back to Deck
Terminal window
Terminal window
[shell]
Flatten Directory Structure
SOURCE Bash
VERSION 1.0
AUTHOR Cododel
A Bash script that flattens nested directory structures by moving all files from subdirectories to the root level. Automatically handles filename conflicts and cleans up empty directories.
Features
- Recursive file moving: Finds all files in nested subdirectories
- Conflict resolution: Automatically renames duplicates with
_1,_2, etc. - Extension preservation: Maintains file extensions when renaming
- Empty directory cleanup: Removes empty subdirectories after moving
- Safe operations: Uses absolute paths to prevent errors
Use Case
Perfect for cleaning up messy download folders, organizing extracted archives, or consolidating scattered files:
# Flatten a messy downloads folder./flatten-dirs.sh ~/Downloads/project
# Consolidate extracted archive./flatten-dirs.sh ./extracted_files
# Clean up nested photo directories./flatten-dirs.sh ~/Pictures/vacationBefore & After Example
Before:
my-folder/├── file1.txt├── subdir1/│ ├── file2.txt│ └── file1.txt (conflict!)└── subdir2/ └── nested/ └── file3.jpgAfter:
my-folder/├── file1.txt├── file1_1.txt (renamed to avoid conflict)├── file2.txt└── file3.jpgHow It Works
- Validation: Checks if directory exists
- Absolute path: Converts input to absolute path
- File discovery: Finds all files at depth ≥2
- Conflict detection: Checks for existing files with same name
- Smart renaming: Adds
_Nsuffix before extension if conflict - Moving: Relocates files to root directory
- Cleanup: Removes empty subdirectories
Usage
# Basic usage./flatten-dirs.sh <directory>
# Example./flatten-dirs.sh ~/Downloads/nested_folderOutput Example
Moved: /path/to/folder/subdir/file.txt -> /path/to/folder/file.txtMoved: /path/to/folder/another/file.txt -> /path/to/folder/file_1.txtMoved: /path/to/folder/deep/nested/image.jpg -> /path/to/folder/image.jpgDirectory structure flattenedSource Code
flatten-dirs.sh
#!/bin/bash
# Check if directory is providedif [ $# -ne 1 ]; then echo "Usage: $0 <directory>" exit 1fi
# Check if directory existsif [ ! -d "$1" ]; then echo "Error: Directory '$1' does not exist" exit 1fi
# Convert to absolute pathtarget_dir=$(realpath "$1")
# Find all files in subdirectories and move them to rootfind "$target_dir" -type f -mindepth 2 | while read -r file; do filename=$(basename "$file") dest="$target_dir/$filename"
# Handle filename conflicts counter=1 while [ -f "$dest" ]; do base="${filename%.*}" ext="${filename##*.}" if [ "$base" = "$ext" ]; then # File has no extension dest="$target_dir/${base}_${counter}" else # File has extension dest="$target_dir/${base}_${counter}.${ext}" fi ((counter++)) done
# Move the file mv "$file" "$dest" echo "Moved: $file -> $dest"done
# Remove empty directoriesfind "$target_dir" -type d -mindepth 1 -empty -delete
echo "Directory structure flattened"Safety Notes
- ⚠️ This operation modifies your filesystem
- 🔒 Consider making a backup before running
- 📝 Review the output to see which files were moved
- 🗑️ Empty directories are permanently deleted