#!/bin/bash # Script to concatenate all files in a directory and its subdirectories # into a single markdown file with filenames and content preserved. # Usage: ./concatenate_files_to_markdown.sh [source_directory] [output_file.md] # Defaults: source_directory = current directory, output_file.md = consolidated.md SOURCE_DIR="${1:-.}" OUTPUT_FILE="${2:-consolidated.md}" # Empty or create the output file > "$OUTPUT_FILE" # Function to get the file extension for markdown code block language get_file_extension() { local filename="$1" local ext="\${filename##*.}" # If no extension or filename equals ext, return empty string if [[ "\$filename" == "\$ext" ]]; then echo "" else # sanitize extension to avoid weird chars echo "\$ext" | tr '[:upper:]' '[:lower:]' fi } # Export function in case subshell required (not strictly necessary here) export -f get_file_extension # Find all files, sort them for consistent order find "\$SOURCE_DIR" -type f | sort | while IFS= read -r file; do # Get relative path relpath="\${file#\$SOURCE_DIR/}" # fallback if prefix not found if [[ "\$relpath" == "\$file" ]]; then relpath="\$file" fi # Get file extension for code block language lang=\$(get_file_extension "\$file") # Append filename as markdown header with inline code formatting echo "" >> "\$OUTPUT_FILE" echo "### \`\$relpath\`" >> "\$OUTPUT_FILE" echo "" >> "\$OUTPUT_FILE" # Append code block start with language if available if [[ -n "\$lang" ]]; then echo "~~~\$lang" >> "\$OUTPUT_FILE" else echo "~~~" >> "\$OUTPUT_FILE" fi # Append file content cat "\$file" >> "\$OUTPUT_FILE" # Append code block end echo "~~~" >> "\$OUTPUT_FILE" done echo "All files concatenated into \$OUTPUT_FILE"