Created
June 22, 2025 18:25
-
-
Save rmohta/7c7bc01e407b04f11ab203221f2f7dba to your computer and use it in GitHub Desktop.
Like flatMap, but for directories on your computer.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/bash | |
# Script Name: flatDirectory | |
# Purpose: Copies all files from the specified folder path and its nested subdirectories | |
# into a new directory named 'flatDirectory' within the source directory. | |
# Files from subdirectories will have their names prefixed with the | |
# subdirectory path relative to the source folder (e.g., 'subdir_filename.txt'). | |
# Check if a source directory is provided as an argument | |
if [ -z "$1" ]; then | |
echo "Usage: $0 <source_folder_path>" | |
echo "Example: $0 ~/Documents/my_project" | |
exit 1 | |
fi | |
SOURCE_DIR="$1" | |
# Check if the provided source directory exists and is a directory | |
if [ ! -d "$SOURCE_DIR" ]; then | |
echo "Error: Source directory '$SOURCE_DIR' does not exist or is not a directory." | |
exit 1 | |
fi | |
# Define the target flat directory name (created inside the SOURCE_DIR) | |
FLAT_DIR="$SOURCE_DIR/flatDirectory" | |
# Create the flat directory if it doesn't exist | |
# The -p option ensures parent directories are also created if needed, and | |
# suppresses errors if the directory already exists. | |
echo "Creating target directory: $FLAT_DIR/" | |
mkdir -p "$FLAT_DIR" | |
echo "Copying files from '$SOURCE_DIR'..." | |
# Find all regular files (f) starting from the specified source directory | |
# -print0 ensures that filenames with spaces or special characters are handled correctly | |
# The while loop reads null-separated input from find | |
find "$SOURCE_DIR" -type f -print0 | while IFS= read -r -d $'\0' filepath; do | |
# Remove the SOURCE_DIR prefix from the filepath to get the path relative to SOURCE_DIR | |
# This gives us the path relative to the source directory, e.g., "subdir/file.txt" or "file.txt" | |
# Ensure the trailing slash is included in the prefix to match directory boundaries correctly | |
relative_path="${filepath#$SOURCE_DIR/}" | |
# Extract the base filename (e.g., "file.txt") | |
filename=$(basename "$relative_path") | |
# Extract the directory part relative to the source directory (e.g., "subdir") | |
# If the file is directly in SOURCE_DIR, directory_part will be ".". | |
directory_part=$(dirname "$relative_path") | |
# Construct the new filename for the flattened directory | |
# If the file is in the root of the SOURCE_DIR, directory_part will be ".", so we just use the original filename. | |
# Otherwise, replace '/' with '_' in the directory_part and prepend it to the filename. | |
if [ "$directory_part" = "." ]; then | |
# File is directly in the source folder, no prefix needed | |
new_filename="$filename" | |
else | |
# File is in a subdirectory of the source folder, prepend flattened path | |
# Replace all '/' with '_' in the directory_part | |
flattened_prefix=$(echo "$directory_part" | tr '/' '_') | |
new_filename="${flattened_prefix}_${filename}" | |
fi | |
# Copy the file to the flat directory with the new name | |
# -v provides verbose output, showing which files are being copied | |
cp -v "$filepath" "$FLAT_DIR/$new_filename" | |
done | |
echo "Operation complete. All files copied to $FLAT_DIR/." |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment