#!/bin/bash # ------------------------------------------------------------------ # Author: ChatGPT # Generated on: $(date '+%Y-%m-%d') # # This script recursively creates or updates a table-of-contents README file in each # non-hidden directory. The file is named "Folder Name - README.md". # # Each README includes: # - An author/date header. # - A header with the folder's name. # - An alphabetically sorted list of immediate subdirectories, # with links to that subdirectory’s own README. # - An alphabetically sorted list of immediate files (excluding # the generated README). # # Hidden directories (or any directory under a hidden parent such as .git) # are skipped. # # This version optimizes updates by comparing the new content (ignoring the header) # to the existing file and only updating if there are changes. # ------------------------------------------------------------------ # If you want to remove existing README files, comment out or remove the next line. # find . -type f -name '* - README.md' -delete # Set the base directory (change "." if necessary) base_dir="." # Recursively process every directory starting from base_dir. find "$base_dir" -type d -print0 | while IFS= read -r -d '' dir; do # Skip directories that are hidden or are within a hidden directory (like .git) if [[ "$(basename "$dir")" == .* ]] || [[ "$dir" == *"/.git"* ]]; then continue fi # For the top-level directory, use its actual name (using $PWD) instead of "." if [ "$dir" = "$base_dir" ]; then base=$(basename "$PWD") else base=$(basename "$dir") fi # Define the path for the README file: "Folder Name - README.md" readme="$dir/${base} - README.md" # Create a temporary file to hold the new content. tmpfile=$(mktemp) # Write the header into the temporary file. # (We include the date here but will ignore it when comparing changes.) { echo "Generated by ChatGPT on $(date '+%Y-%m-%d')" echo "" echo "# Table of Contents for ${base}" echo "" } > "$tmpfile" ######################### # Process Subdirectories ######################### subdirs=() # Find immediate subdirectories (depth 1) in the current directory, skipping hidden ones. while IFS= read -r -d '' subdir; do sub_basename=$(basename "$subdir") if [ -n "$sub_basename" ]; then subdirs+=( "$sub_basename" ) fi done < <(find "$dir" -mindepth 1 -maxdepth 1 -type d ! -name '.*' -print0) if [ ${#subdirs[@]} -gt 0 ]; then # Sort subdirectory names alphabetically. mapfile -t sorted_subdirs < <(printf "%s\n" "${subdirs[@]}" | sort) echo "## Subdirectories" >> "$tmpfile" for sub in "${sorted_subdirs[@]}"; do # Build the link to the subdirectory's README file. # Format: [[Subfolder/Subfolder - README]] line="- [[${sub}/${sub} - README]]" printf "%s\n" "$line" >> "$tmpfile" done echo "" >> "$tmpfile" fi ################# # Process Files ################# files=() # Find immediate files (depth 1), excluding the generated README file. while IFS= read -r -d '' file; do fbase=$(basename "$file") if [ -n "$fbase" ]; then files+=( "$fbase" ) fi done < <(find "$dir" -mindepth 1 -maxdepth 1 -type f ! -path "$readme" -print0) if [ ${#files[@]} -gt 0 ]; then # Sort file names alphabetically. mapfile -t sorted_files < <(printf "%s\n" "${files[@]}" | sort) echo "## Files" >> "$tmpfile" for f in "${sorted_files[@]}"; do line="- [[${f}]]" printf "%s\n" "$line" >> "$tmpfile" done echo "" >> "$tmpfile" fi # If the README file exists, compare its body (ignoring the header) with the new content. # Here, we assume the header is the first two lines (the attribution and a blank line). if [ -f "$readme" ]; then if diff -q <(tail -n +3 "$tmpfile") <(tail -n +3 "$readme") >/dev/null; then # No change in the body; do not update. rm "$tmpfile" continue fi fi # If new or changed, move the temporary file to the target README. mv "$tmpfile" "$readme" done