Skip to content

Instantly share code, notes, and snippets.

@bouzou4
Last active June 13, 2024 12:55
Show Gist options
  • Save bouzou4/c2d46a27376802abf785e7640aba3933 to your computer and use it in GitHub Desktop.
Save bouzou4/c2d46a27376802abf785e7640aba3933 to your computer and use it in GitHub Desktop.
Concatenates the contents of specified file types into a single file, with headers indicating the source files.
#!/bin/zsh
# Help message function
function show_help() {
cat <<- EOF
Usage: ${0} [OPTIONS] -e EXTENSIONS
Concatenates the contents of specified file types into a single file, with headers indicating the source files.
OPTIONS:
-d Directory to start looking for files (default is current directory)
-e Extensions to include, comma-separated. Example: js,jsx,ts
-x Directories to exclude, comma-separated. Example: node_modules,dist
-o Output file (default is the name of the directory it begins looking in)
-h Show this help message and exit.
EXAMPLE:
${0} -d src -e ts,tsx,mts,js,jsx,json,md -x node_modules,dist,coverage -o combined.txt
EOF
}
# Default values
extensions=() # No default file extensions
excludes=() # Default directories to exclude
start_dir=$(pwd) # Default start directory is the current directory
output_file="" # No default, will be set based on start_dir
# Parse options
while getopts ":d:e:x:o:h" opt; do
case ${opt} in
d)
start_dir=$OPTARG
;;
e)
IFS=',' read -r -A extensions <<< "$OPTARG"
;;
x)
IFS=',' read -r -A excludes <<< "$OPTARG"
;;
o)
output_file=$OPTARG
;;
h)
show_help
return 0
;;
\?)
echo "Invalid option: $OPTARG" 1>&2
show_help
return 1
;;
:)
echo "Option -$OPTARG requires an argument." 1>&2
show_help
return 1
;;
esac
done
# Set default output file name if not specified
if [[ -z $output_file ]]; then
output_file="${start_dir:t}.txt" # Set default output file name to directory name with .txt extension
fi
# Ensure at least one extension is specified
if [[ ${#extensions[@]} -eq 0 ]]; then
echo "At least one file extension must be specified using -e." 1>&2
show_help
return 1
fi
# Building the find command
find_command="find ${start_dir}"
# Exclude directories
for dir in "${excludes[@]}"; do
find_command+=" -not \( -path \"*/${dir}\" -prune \) "
done
# Concatenate additional extensions with OR condition
find_command+=" -type f -name '*.${extensions[0]}'"
for ((i = 1; i < ${#extensions[@]}; i++)); do
find_command+=" -o -name '*.${extensions[i]}'"
done
# Execute the find command and process files
eval $find_command | while read filename; do
echo "// ~~~ From file ${filename} ~~~\n" >> $output_file
cat "${filename}" >> $output_file
echo "\n\n" >> $output_file
done
echo "Files have been combined into ${output_file}."
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment