Skip to content

Instantly share code, notes, and snippets.

@hassan404
Last active February 6, 2025 11:46
Show Gist options
  • Save hassan404/837619144d090b97cb617837d3ec229b to your computer and use it in GitHub Desktop.
Save hassan404/837619144d090b97cb617837d3ec229b to your computer and use it in GitHub Desktop.
File Content Combiner
import os
import sys
def process_path(path, extension=None):
"""
Process a single path which can be either a file or directory.
If it's a directory, recursively process all files with given extension.
If it's a file, process it directly.
Args:
path (str): Path to file or directory
extension (str, optional): File extension to filter by when processing directories
"""
# Get current working directory for relative path calculation
cwd = os.getcwd()
abs_path = os.path.abspath(path)
if os.path.isfile(abs_path):
# If extension is specified, skip files that don't match
if extension and not path.endswith(f".{extension}"):
return
relative_path = os.path.relpath(abs_path, cwd)
try:
with open(abs_path, "r", encoding="utf-8") as f:
print(f"# Start of {relative_path}")
print(f.read())
print(f"# End of {relative_path}\n")
except Exception as e:
print(f"Error processing {relative_path}: {e}", file=sys.stderr)
elif os.path.isdir(abs_path):
# Walk through the directory recursively
for root, _, files in os.walk(abs_path):
for file in files:
# Skip files that don't match extension if one is specified
if extension and not file.endswith(f".{extension}"):
continue
file_path = os.path.join(root, file)
relative_path = os.path.relpath(file_path, cwd)
try:
with open(file_path, "r", encoding="utf-8") as f:
print(f"# Start of {relative_path}")
print(f.read())
print(f"# End of {relative_path}\n")
except Exception as e:
print(f"Error processing {relative_path}: {e}", file=sys.stderr)
else:
print(f"Error: Path not found - {path}", file=sys.stderr)
def combine_paths(paths, extension=None):
"""
Combines contents of specified paths, which can be files or directories.
For directories, combines all files with given extension recursively.
Args:
paths (list): List of file and/or directory paths
extension (str, optional): File extension to filter by when processing directories
"""
for path in paths:
process_path(path, extension)
if __name__ == "__main__":
if len(sys.argv) < 2:
print("Usage: python combine.py [-e extension] path1 [path2 path3 ...]")
print(" -e: Optional file extension filter for directories (without dot)")
print(" paths: Files and/or directories to process")
sys.exit(1)
# Parse command line arguments
args = sys.argv[1:]
extension = None
paths = []
i = 0
while i < len(args):
if args[i] == "-e" and i + 1 < len(args):
extension = args[i + 1]
i += 2
else:
paths.append(args[i])
i += 1
if not paths:
print("Error: No paths specified")
sys.exit(1)
try:
combine_paths(paths, extension)
except Exception as e:
print(f"An error occurred: {e}", file=sys.stderr)
@hassan404
Copy link
Author

hassan404 commented Feb 6, 2025

File Content Combiner

A Python utility script that combines and displays the contents of multiple files and directories. Perfect for quickly viewing or concatenating text files, with support for recursive directory traversal and file extension filtering.

Features:

  • Process both individual files and entire directories
  • Recursive directory traversal
  • Optional file extension filtering
  • Maintains file path context in output
  • UTF-8 encoding support
  • Error handling for file operations
  • Relative path reporting

Usage:
python combine.py [-e extension] path1 [path2 path3 ...]
-e: Optional file extension filter for directories (without dot)
paths: One or more files and/or directories to process

Example:
python combine.py -e py ./src ./tests script.py > combined_file.py

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment