open terminal
- spotlight search for
terminal
1. create folders & files
Copy
mkdir -p ~/Developer
mkdir -p ~/Developer/init-macOS
cd ~/Developer/init-macOS
touch dir-list.sh
# nano dir-list.sh
open dir-list.sh
Copy
#!/usr/bin/env bash
#
# SCRIPT: list_dirs_and_files.sh
# PURPOSE:
# • Snapshot the current directory’s structure into a single file.
# • Section 0: Show statistics (total folders and files).
# • Section 1: List immediate subdirectories (“FOLDERS ONLY”).
# • Section 2: Append a full recursive listing (files + folders).
# • Print an initial ETA message (in blue).
# • Print a final confirmation message (in green).
# • Save into: {EXPORT_DIR}/SNAP-{basename_of_dir}-(yy.m.d-h.m).txt
#
# – EXPORT_DIR: where to write the output (default: "$HOME/Desktop")
# – basename_of_dir: name of the current directory.
# – yy: two-digit year (e.g., 25 for 2025).
# – m: month without leading zero (e.g., 6 for June).
# – d: day without leading zero (e.g., 3).
# – h: hour (24h) without leading zero if <10.
# – m: minute with leading zero if <10.
#
# Example output file:
# ~/Desktop/SNAP-Developer-(25.6.3-13.05).txt
#
# DEPENDENCIES:
# • BSD-compatible date (macOS default).
# • sed (for stripping leading zeros).
# • find, awk, sort (standard Unix utilities).
# • ANSI escape support in the terminal.
#
# AUTHOR: Your Name
# DATE: 2025-06-03
#
# —————————————————————————————————————————————————————————————
# 0. CONFIGURATION: Set where the snapshot file should be saved.
# By default, this points to "$HOME/Desktop". You may change it.
# —————————————————————————————————————————————————————————————
EXPORT_DIR="$HOME/Desktop"
# Ensure EXPORT_DIR exists (create if necessary)
if [[ ! -d "$EXPORT_DIR" ]]; then
mkdir -p "$EXPORT_DIR" || {
echo "Error: Could not create directory '$EXPORT_DIR'." >&2
exit 1
}
fi
# —————————————————————————————————————————————————————————————
# 1. DECLARE COLOR VARIABLES (PINK | PURPLE | BLUE | GREEN | RED | NC)
# —————————————————————————————————————————————————————————————
PINK='\033[38;5;200m' # A pink shade (256-color palette)
PURPLE='\033[38;5;93m' # A purple shade
BLUE='\033[38;5;75m' # A blue shade
GREEN='\033[0;32m' # Standard ANSI green
RED='\033[0;31m' # Standard ANSI red
NC='\033[0m' # No Color / reset sequence
# —————————————————————————————————————————————————————————————
# 2. INITIAL MESSAGE: Print ETA (in BLUE)
# —————————————————————————————————————————————————————————————
echo -e "${BLUE}ETA: ~15 sec.${NC}"
# —————————————————————————————————————————————————————————————
# 3. COMPUTE TOTAL NUMBER OF FOLDERS & FILES (using two find commands)
# —————————————————————————————————————————————————————————————
# Ignore patterns: node_modules, .git, .venv, __pycache__, .DS_Store
total_folders=$(
find . \
\( -path "./node_modules" -o -path "*/node_modules" -o -path "./.git" -o -path "*/.git" -o -path "./.venv" -o -path "*/.venv" -o -path "*/__pycache__" -o -name ".DS_Store" \) -prune \
-o -type d -print \
| wc -l
)
total_files=$(
find . \
\( -path "./node_modules" -o -path "*/node_modules" -o -path "./.git" -o -path "*/.git" -o -path "./.venv" -o -path "*/.venv" -o -path "*/__pycache__" -o -name ".DS_Store" \) -prune \
-o -type f -print \
| wc -l
)
# —————————————————————————————————————————————————————————————
# 3a. COMPUTE ADDITIONAL STATISTICS: created timestamp, directory size, largest file
# —————————————————————————————————————————————————————————————
created_on="$(date '+%Y-%m-%d %H:%M:%S')"
dir_full_path="$PWD"
# Compute total size of this directory (human-readable)
total_size="$(du -sh "$dir_full_path" 2>/dev/null | awk '{print $1}')"
# Find largest file (ignoring pruned patterns)
largest_info="$(
find . \
\( -path "./node_modules" -o -path "*/node_modules" -o -path "./.git" -o -path "*/.git" -o -path "./.venv" -o -path "*/.venv" -o -path "*/__pycache__" -o -name ".DS_Store" \) -prune \
-o -type f -print0 \
| xargs -0 du 2>/dev/null \
| sort -n \
| tail -1
)"
largest_file_size="$(echo "$largest_info" | awk '{print $1}')"
largest_file_path="$(echo "$largest_info" | awk '{print $2}')"
# —————————————————————————————————————————————————————————————
# 4. EXTRACT BASE DIRECTORY NAME
# (e.g., if PWD=/Users/you/Developer, dir_name="Developer")
# —————————————————————————————————————————————————————————————
dir_name="$(basename "$PWD")"
# —————————————————————————————————————————————————————————————
# 5. GENERATE RAW TIMESTAMP (TWO-DIGIT FORMAT)
# BSD date on macOS: "yy.mm.dd-HH.MM" (e.g., "25.06.03-13.05")
# —————————————————————————————————————————————————————————————
raw_ts="$(date +'%y.%m.%d-%H.%M')"
# —————————————————————————————————————————————————————————————
# 6. NORMALIZE TIMESTAMP (STRIP LEADING ZEROS FROM MONTH & DAY)
# e.g., "25.06.03-13.05" → "25.6.3-13.05"
# Uses a pair of sed commands to remove “0” when month/day < 10. [oai_citation:2‡discussions.apple.com](https://discussions.apple.com/thread/251141097?utm_source=chatgpt.com) [oai_citation:3‡apple.stackexchange.com](https://apple.stackexchange.com/questions/398952/how-to-identify-the-largest-files-in-a-directory-including-in-its-subdirectories?utm_source=chatgpt.com)
# —————————————————————————————————————————————————————————————
timestamp="$(echo "$raw_ts" \
| sed -E 's/^([0-9]{2})\.0([1-9])\./\1.\2./' \
| sed -E 's/^([0-9]{2}\.[0-9]{1,2})\.0([1-9])-/\1.\2-/')"
# —————————————————————————————————————————————————————————————
# 7. BUILD OUTPUT FILENAME
# Format: SNAP-{dir_name}-(timestamp).txt
# e.g., SNAP-Developer-(25.6.3-13.05).txt
# —————————————————————————————————————————————————————————————
out_file="SNAP-${dir_name}-(${timestamp}).txt"
full_path="$EXPORT_DIR/$out_file"
# Validate that filename is not empty
if [[ -z "$out_file" ]]; then
echo -e "${RED}Error: Generated filename is empty or invalid.${NC}" >&2
exit 1
fi
# —————————————————————————————————————————————————————————————
# 8. WRITE “STATISTICS” AND “FOLDERS ONLY” SECTION
# • Decorative headers
# • STATISTICS: total_folders, total_files
# • FOLDERS ONLY: immediate subdirectories at maxdepth 1
# —————————————————————————————————————————————————————————————
{
echo "╭────────────────────────────────────────────────────────╮"
echo "| STATISTICS FOR '$dir_name' |"
echo "╰────────────────────────────────────────────────────────╯"
echo " Created on: $created_on"
echo " Directory path: $dir_full_path"
echo " Total size: $total_size"
echo " Largest file: $largest_file_size $largest_file_path"
echo " Total folders: $total_folders"
echo " Total files: $total_files"
echo ""
echo "╭────────────────────────────────────────────────────────╮"
echo "| FOLDERS IN '$dir_name' (Immediate Subdirectories) |"
echo "╰────────────────────────────────────────────────────────╯"
# List of folders (strip leading "./"; exclude "." itself)
find . -maxdepth 1 -type d \
| sed 's|^\./||' \
| grep -v '^$' \
| sort
echo ""
} > "$full_path" || {
echo -e "${RED}Error: Could not write 'STATISTICS/FOLDERS ONLY' section to '$full_path'.${NC}" >&2
exit 1
}
# —————————————————————————————————————————————————————————————
# 9. APPEND “RECURSIVE LISTING” SECTION
# • Decorative header
# • Full recursive list (files + folders, including hidden)
# —————————————————————————————————————————————————————————————
{
echo "╭────────────────────────────────────────────────────────╮"
echo "| FULL RECURSIVE LISTING OF '$dir_name' |"
echo "╰────────────────────────────────────────────────────────╯"
find . \
\( -path "./node_modules" -o -path "*/node_modules" -o -path "./.git" -o -path "*/.git" -o -path "./.venv" -o -path "*/.venv" -o -path "*/__pycache__" -o -name ".DS_Store" \) -prune \
-o -mindepth 1 -print \
| sed 's|^\./||' \
| sort \
| awk -F'/' '
{
root = $1
if (root != prev) {
if (prev != "") print "────────────────────────────────────────────────────────────────────"
prev = root
}
indent = (NF-1)*4
printf "%*s%s\n", indent, "", $0
}
'
} >> "$full_path" || {
echo -e "${RED}Error: Could not append 'RECURSIVE LISTING' to '$full_path'.${NC}" >&2
exit 1
}
# —————————————————————————————————————————————————————————————
# 10. FINAL CONFIRMATION: Print “Saved snapshot to:” in GREEN
# —————————————————————————————————————————————————————————————
echo -e "${GREEN}Saved snapshot to: $full_path${NC}"
2. run the script
Copy
cd ~/Developer/init-macOS
chmod +x dir-list.sh
./dir-list.sh
3. check the output
Copy
cd ~/Desktop
ls -l
open .