Last active
February 18, 2025 21:48
-
-
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.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/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