Skip to main content

A simple CLI tool to recursively concatenate all files of a certain extension in a directory into a single file

Project description

concat-all

A simple CLI tool to recursively concatenate all files of a certain extension in a directory into a single file.


Features

  • Concatenate all files with specified extension(s) in a directory tree
  • Supports multiple extensions at once (e.g., .py,.txt)
  • Optionally respects .gitignore rules, including negated patterns (e.g., !important_file.txt), to skip or include files and folders
  • Adds a comment header before each file's content in the output
  • Flexible output file naming and location
  • Dry-run mode to preview changes
  • Exclude specific files or directories using glob patterns
  • Limit directory recursion depth
  • Cross-platform and Python 3.9+ compatible

Installation

Clone the repository and install locally:

git clone https://github.com/mwmuni/concat-all.git
cd concat-all
python -m pip install .

Or use your preferred Python packaging tool.

uvx concat-all

Requirements

  • Python >= 3.9

Usage

Command Line Interface

concat-all <file_extensions> [options]

Arguments

Argument Description Example
<file_extensions> Comma-separated list of file extensions (without or with dot). Use * for all files. py,txt or *.md or *

Options

Option Description Default
--dir_path, -d Directory to search recursively. Current working directory
--output_file, -o Output file name (can include {file_extension} placeholder). dump_{file_extension}.txt
--output_file_dir, -D Directory to save the output file. Current working directory
--comment_prefix, -c Prefix for comment headers before each file's content. //
--gitignore, -i Respect .gitignore rules when selecting files. Disabled
--filename_suffix Suffix to append to the output file name. Supports {timestamp} and {unixtime} placeholders. Disabled
--dry-run, -n List files to be processed and the final output file path without writing any files. Disabled
--exclude <patterns> Comma-separated list of glob patterns to exclude files/directories (e.g., "*.log,temp/*"). Applied after .gitignore. None
--max-depth <depth> Maximum recursion depth. 0 for current directory, 1 for current + direct children, etc. -1 (unlimited)

Examples

Concatenate all .py files in the current directory and subdirectories:

concat-all py

Concatenate .py and .txt files, saving output to a specific directory:

concat-all py,txt -D ./output_dir

Concatenate all files regardless of extension:

concat-all * -o all_files.txt

Concatenate .md files, respecting .gitignore:

concat-all md --gitignore

Change the comment prefix to #:

concat-all py -c "#"

Concatenate all .py files with a timestamp appended to the output file name:

concat-all py -o result.txt --filename_suffix "_{timestamp}"

Perform a dry run to see which .java files would be concatenated:

concat-all java --dry-run

Concatenate .ts files, excluding all files in node_modules and any *.test.ts files:

concat-all ts --exclude "node_modules/*,*.test.ts"

Concatenate .log files only from the current directory (no subdirectories):

concat-all log --max-depth 0

Concatenate .cfg files from the current directory and its direct children, respecting .gitignore:

concat-all cfg --max-depth 1 --gitignore

How it works

  • Recursively walks the specified directory up to --max-depth if provided.
  • Filters files by extension(s) or includes all files with *.
  • Optionally skips files/directories matching .gitignore patterns (supports negated patterns).
  • Skips files/directories matching user-provided --exclude glob patterns.
  • If not in --dry-run mode, concatenates file contents into a single output file.
  • Adds a comment header before each file's content indicating its path (in actual output).
  • In --dry-run mode, lists files that would be processed and the intended output file.

Programmatic Usage

You can also use concat-all as a Python module:

from concat_all import concat_files

concat_files(
    dir_path="path/to/dir",
    file_extensions="py,txt",
    output_file="./output/dump_{file_extension}.txt",
    comment_prefix="//",
    use_gitignore=True,
    force=False
)

Notes

  • The output file name supports the placeholder {file_extension} which will be replaced with the concatenated extensions or 'all' if using *.
  • The tool skips binary files or files it cannot read.
  • The output file itself is automatically excluded from concatenation.

License

MIT License


Author

Matthew Muller


Version

0.1.0


Enjoy! 😊

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

concat_all-0.2.0.tar.gz (9.2 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

concat_all-0.2.0-py3-none-any.whl (7.2 kB view details)

Uploaded Python 3

File details

Details for the file concat_all-0.2.0.tar.gz.

File metadata

  • Download URL: concat_all-0.2.0.tar.gz
  • Upload date:
  • Size: 9.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for concat_all-0.2.0.tar.gz
Algorithm Hash digest
SHA256 860a311abadbad54e605fda9a6705267b427985b552d87f8bae3dd89d3bb5e23
MD5 e64e7d9cb736a403d5ca7c3999c4bcba
BLAKE2b-256 525b2f9cde2b628787db3a6e8f2dd097773ee82f01046cedaa8534f40f71575b

See more details on using hashes here.

Provenance

The following attestation bundles were made for concat_all-0.2.0.tar.gz:

Publisher: python-publish.yml on mwmuni/concat-all

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file concat_all-0.2.0-py3-none-any.whl.

File metadata

  • Download URL: concat_all-0.2.0-py3-none-any.whl
  • Upload date:
  • Size: 7.2 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for concat_all-0.2.0-py3-none-any.whl
Algorithm Hash digest
SHA256 1f8f7a99d8c41f64fe3db2acac61dfbdd8aa49e35cba1bb73e68cc78c1a44130
MD5 8a41889a510320eadbcd61d16a9796d9
BLAKE2b-256 a76ab90146cb73ba7bd1f715c327f9faa5c72fec6770870439190ba8a5be4417

See more details on using hashes here.

Provenance

The following attestation bundles were made for concat_all-0.2.0-py3-none-any.whl:

Publisher: python-publish.yml on mwmuni/concat-all

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page