#!/bin/bash # Function to get relative path from given absoule path & base path get_relative_path() { local absolute_path="$1" local base_path="$2" # Remove trailing slashes for consistency absolute_path="${absolute_path%/}" base_path="${base_path%/}" # Convert both paths to arrays IFS='/' read -r -a absolute_parts <<< "$absolute_path" IFS='/' read -r -a base_parts <<< "$base_path" # Find the common prefix length local common_length=0 while [[ $common_length -lt ${#base_parts[@]} && $common_length -lt ${#absolute_parts[@]} && "${base_parts[$common_length]}" == "${absolute_parts[$common_length]}" ]]; do ((common_length++)) done # Calculate the number of directories to go up from the base path local up_dirs=$(( ${#base_parts[@]} - common_length - 1 )) # Construct the relative path local relative_path="" for ((i = 0; i < up_dirs; i++)); do relative_path+="../" done # Add the remaining parts of the absolute path for ((i = common_length; i < ${#absolute_parts[@]}; i++)); do relative_path+="${absolute_parts[$i]}" if [[ $i -lt $((${#absolute_parts[@]} - 1)) ]]; then relative_path+="/" fi done echo "$relative_path" } # 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 "" >> "$output_file" else echo "${comment_prefix} @file $filepath" >> "$output_file" fi cat "$file" >> "$output_file" echo -e "\n" >> "$output_file" done echo "Concatenation complete. Output saved to $output_file"