Skip to content

Instantly share code, notes, and snippets.

@isurfer21
Last active May 21, 2025 08:27
Show Gist options
  • Save isurfer21/3953c431723da6c429c209c62fa7b7bb to your computer and use it in GitHub Desktop.
Save isurfer21/3953c431723da6c429c209c62fa7b7bb to your computer and use it in GitHub Desktop.
Created a bash script to concatenate all the files in the directory and their sub-directories (of source code) along with their filename into single consolidated file in markdown format persisting file type
#!/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"
@isurfer21
Copy link
Author

The task is to create a bash script that will:

  • Traverse the directory recursively including subdirectories.
  • For each file, append its filename and contents to a single consolidated markdown file.
  • The filename should be included in the markdown file, preserving file type, likely done with code fences and the correct language extension or file type.
  • The output should be a single markdown file with sections for each file indicating the filename and the file content inside appropriate markdown code blocks.
  • We should detect the file extension and use it as the language identifier for the markdown code block.

Plan for the script:

  • Accept as inputs (optional) the directory (default current directory) and output markdown file (default e.g. consolidated.md).
  • Use find to get all files recursively.
  • For each file:
    • Get file name relative to the root directory.
    • Get file extension, use it as the language for the markdown code block.
    • Append a markdown header with the filename (like ### filename).
    • Append the file content wrapped in triple backticks with file extension as language identifier.
  • Use echo or printf to append to the file.

I've prepared a robust bash script with comments.

No extra dependencies needed. The script will be runnable as-is.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment