Obsidian/reddup.sh

122 lines
4.0 KiB
Bash
Executable File
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/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:
# - A header with an author/date line.
# - A header with the folder's name.
# - An alphabetically sorted list of immediate subdirectories, with links
# to that subdirectorys 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.
#
# The script only updates a README if the "body" (everything from line 3 on)
# has changed. It also prints a progress indicator like "[x/y] Updated: {dir}".
# ------------------------------------------------------------------
# Set the base directory (change "." if necessary)
base_dir="."
# Build an array of directories to process.
dirs=()
while IFS= read -r -d '' dir; do
# Skip directories whose basename starts with a dot or whose path contains "/.git"
if [[ "$(basename "$dir")" == .* ]] || [[ "$dir" == *"/.git"* ]] || [[ "$dir" == *"/.obsidian"* ]] ; then
continue
fi
dirs+=( "$dir" )
done < <(find "$base_dir" -type d -print0)
total=${#dirs[@]}
count=0
# Process each directory in the array.
for dir in "${dirs[@]}"; do
count=$((count+1))
# For the top-level directory, use the actual name (using $PWD); otherwise, use the directory's basename.
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.
{
echo "Generated by ChatGPT on $(date '+%Y-%m-%d')"
echo ""
echo "# Table of Contents for ${base}"
echo ""
} > "$tmpfile"
#########################
# Process Subdirectories
#########################
subdirs=()
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
# Link format: [[Subfolder/Subfolder - README]]
line="- [[${sub}/${sub} - README]]"
printf "%s\n" "$line" >> "$tmpfile"
done
echo "" >> "$tmpfile"
fi
#################
# Process Files
#################
files=()
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 already exists, compare its body (from line 3 onward)
# with the new content (ignoring the first two lines, which contain the date header).
if [ -f "$readme" ]; then
if diff -q <(tail -n +3 "$tmpfile") <(tail -n +3 "$readme") >/dev/null; then
rm "$tmpfile"
echo "[$count/$total] No change: $dir"
continue
fi
fi
# Update (or create) the README.
mv "$tmpfile" "$readme"
echo "[$count/$total] Updated: $dir"
done