Skip to content

Instantly share code, notes, and snippets.

@isurfer21
Last active June 11, 2025 12:25
Show Gist options
  • Save isurfer21/bec2c4c5d66f4e9024babbd9b39aeb36 to your computer and use it in GitHub Desktop.
Save isurfer21/bec2c4c5d66f4e9024babbd9b39aeb36 to your computer and use it in GitHub Desktop.
Here's a Bash script that recursively traverses a directory, reads each file, and concatenates them into a single output file. It adds a comment at the top of each file's content using the appropriate syntax based on the file extension.
#!/bin/bash
# Function to get directory name from path
get_dirname() {
local input_path="$1"
local resolved_path
# Check if realpath exists
if command -v realpath >/dev/null 2>&1; then
# Try to resolve the path fully
resolved_path=$(realpath "$input_path" 2>/dev/null)
elif command -v readlink >/dev/null 2>&1; then
resolved_path=$(readlink -f "$input_path" 2>/dev/null)
else
# Fallback: use the input path as is
resolved_path="$input_path"
fi
# If resolution failed (empty), fallback to input path
if [ -z "$resolved_path" ]; then
resolved_path="$input_path"
fi
# Check if the resolved path is a directory
if [ -d "$resolved_path" ]; then
# Return the directory name itself
echo "$resolved_path"
else
# Get dirname of the resolved path
dirname "$resolved_path"
fi
}
# Function to determine comment syntax based on file extension
get_comment_prefix() {
case "$1" in
*.py|*.sh|*.pl|*.rb|*.r|*.yaml|*.yml|*.toml|*.ini|*.conf|*.cfg) echo "#" ;;
*.c|*.cpp|*.h|*.java|*.js|*.ts|*.css|*.go|*.swift|*.kt|*.scala|*.cs|*.fs) echo "//" ;;
*.vb) echo "'" ;; # Visual Basic uses single quote for comments
*.html|*.xml|*.cshtml|*.razor) echo "<!--" ;;
*.php) echo "//" ;;
*.sql) echo "--" ;;
*) echo "#" ;; # Default to hash
esac
}
# Check if input directory is provided and exists
if [ -z "$1" ] || [ ! -d "$1" ]; then
echo "Error: Please provide a valid directory path."
exit 1
fi
# Get output filename from input directory path
output_filename=$(get_dirname "$1")
# Output file
output_file="$output_filename.txt"
> "$output_file" # Clear the output file if it exists
# Traverse all files in the directory and subdirectories
find "$1" -type f | while IFS= read -r file; do
ext="${file##*.}"
comment_prefix=$(get_comment_prefix "$file")
if [[ "$comment_prefix" == "<!--" ]]; then
echo "${comment_prefix} @file $file -->" >> "$output_file"
else
echo "${comment_prefix} @file $file" >> "$output_file"
fi
cat "$file" >> "$output_file"
echo -e "\n" >> "$output_file"
done
echo "Concatenation complete. Output saved to $output_file"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment