#!/bin/bash # Initialize variables output_file="claude.txt" current_filter="" directories=() # Parse command line arguments while [[ $# -gt 0 ]]; do case $1 in -f|--filter) if [ -n "$2" ]; then current_filter="$2" shift 2 else echo "Error: No filter pattern specified after -f/--filter" >&2 exit 1 fi ;; *) # Check if the argument is a valid directory if [ -d "$1" ]; then # Store directory with its associated filter directories+=("$1") directories+=("$current_filter") shift 1 else echo "Error: Directory '$1' does not exist" >&2 exit 1 fi ;; esac done # Clear/create output file > "$output_file" # Add header echo "Directory Tree:" > "$output_file" echo "=============" >> "$output_file" # Process each directory for ((i=0; i<${#directories[@]}; i+=2)); do dir="${directories[i]}" filter="${directories[i+1]}" echo "Processing directory: $dir (filter: ${filter:-none})" # Add directory to output echo -e "\n=== Directory: $dir ===" >> "$output_file" # Change to target directory original_dir=$(pwd) cd "$dir" || continue # Generate directory tree for this directory if command -v tree &> /dev/null; then if [ -f ".gitignore" ]; then tree -I "$(git check-ignore * .*)" >> "$output_file" else tree >> "$output_file" fi else find . -type f -name "*" | sort >> "$output_file" fi # List files based on filter echo -e "\nFile Contents for $dir:" >> "$output_file" echo "=======================" >> "$output_file" # Get list of files to process files_to_process=() if [ -z "$filter" ]; then # No filter, use git ls-files if git repo, otherwise use find if git rev-parse --is-inside-work-tree &> /dev/null; then mapfile -d $'\0' files_to_process < <(git ls-files -z --cached --others --exclude-standard) else mapfile -d $'\0' files_to_process < <(find . -type f -not -path "*/\.*" -print0) fi else # Use filter if git rev-parse --is-inside-work-tree &> /dev/null; then mapfile -d $'\0' files_to_process < <(git ls-files -z --cached --others --exclude-standard | grep -z "$filter$") else mapfile -d $'\0' files_to_process < <(find . -type f -name "*$filter" -print0) fi fi # Process each file for file in "${files_to_process[@]}"; do # Skip the output file itself if [ "$file" = "$output_file" ] || [ "$file" = "./$output_file" ]; then continue fi # Skip non-existent files if [ ! -f "$file" ]; then continue fi # Skip binary files if file "$file" | grep -q "binary"; then echo "Skipping binary file: $file" >> "$output_file" continue fi echo -e "\n=== File: $dir/$file ===" >> "$output_file" echo -e "------------------------" >> "$output_file" cat "$file" >> "$output_file" done # Return to original directory cd "$original_dir" || exit 1 done echo "Concatenation complete. Output written to $output_file"