Bulk text replacement in files using dictionary mappings
Project description
textswap
Bulk text replacement in files using dictionary mappings.
Replace text across multiple files using find/replace dictionaries. Supports bidirectional replacement (keys-to-values or values-to-keys).
Installation
pip install textswap
Quick Start
- Create a config file (
config.json):
{
"dictionaries": {
"example": {
"old_text": "new_text",
"foo": "bar"
}
},
"ignore_extensions": [".exe", ".bin"],
"ignore_directories": ["node_modules", ".git"],
"ignore_file_prefixes": [".", "_"]
}
- Run:
textswap -f ./my_folder -d 1
Usage
# Interactive mode
textswap
# With options
textswap --folder ./src --direction 1 --config my_config.json
# Dry run (preview changes with diff output)
textswap -f ./src -d 1 --dry-run
# Reverse direction (values-to-keys)
textswap -f ./src -d 2
Options
| Option | Short | Description |
|---|---|---|
--folder |
-f |
Folder to process |
--direction |
-d |
1 = keys-to-values, 2 = values-to-keys |
--config |
-c |
Path to config file (default: config.json) |
--dict-name |
-n |
Dictionary name (auto-selects if only one) |
--dry-run |
Preview changes without modifying files |
Config Format
{
"dictionaries": {
"my_replacements": {
"find_this": "replace_with_this",
"old": "new"
}
},
"ignore_extensions": [".exe", ".dll"],
"ignore_directories": ["node_modules", "venv"],
"ignore_file_prefixes": [".", "_"]
}
How It Works
- Load config: Reads your JSON config file containing replacement dictionaries
- Walk directory: Recursively traverses the target folder
- Filter files: Skips files matching ignore rules (extensions, prefixes, directories)
- Read & replace: For each file, reads content and applies all replacements from the dictionary
- Write back: Saves modified files (or shows diff in dry-run mode)
All files are processed as UTF-8. Non-UTF-8 files are automatically skipped with a warning.
Dry Run Output
The --dry-run flag shows exactly what would change without modifying files:
$ textswap -f ./src -d 1 --dry-run
Dry run mode - no files will be modified
Would modify: ./src/example.txt
--- a/./src/example.txt
+++ b/./src/example.txt
@@ -1 +1 @@
-Hello world
+Goodbye world
Processed 5 files, 1 modified
Multiple Dictionaries
You can define multiple dictionaries in your config for different replacement scenarios:
{
"dictionaries": {
"encode": {
"secret": "s3cr3t",
"password": "p4ssw0rd"
},
"localize_fr": {
"Hello": "Bonjour",
"Goodbye": "Au revoir"
}
}
}
Select which dictionary to use with --dict-name:
textswap -f ./src -d 1 -n encode
textswap -f ./src -d 1 -n localize_fr
Troubleshooting
"Invalid JSON in config file"
Your config file has a syntax error. Common issues:
- Missing commas between items
- Trailing commas (not allowed in JSON)
- Unquoted strings
Use a JSON validator to check your config.
"Config must contain a 'dictionaries' object"
Your config file is missing the required dictionaries key:
{
"dictionaries": {
"my_dict": {"find": "replace"}
}
}
Files being skipped
Files are skipped for these reasons (shown in output):
- Not UTF-8 encoded: Binary files or files with different encoding
- Permission denied: No read/write access to the file
No files modified
Check that:
- Your search terms exactly match the file content (case-sensitive)
- Files aren't being filtered by ignore rules
- The target folder contains text files
Replacements happening in wrong order
Replacements are applied in dictionary key order. If you have overlapping patterns (e.g., "hello" and "hello world"), the first match wins. Consider using more specific patterns.
Use Cases
- Encoding/decoding: Obfuscate or de-obfuscate text in files
- Localization: Batch replace text for different languages
- Refactoring: Rename variables, functions, or classes across a codebase
- Template substitution: Replace placeholders with actual values
- Migration: Update deprecated API calls or import paths
Encoding
All files are read and written as UTF-8. Files that cannot be decoded as UTF-8 (binary files, files with other encodings) are automatically skipped and reported in the output.
License
GPL v3
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file textswap-0.2.1.tar.gz.
File metadata
- Download URL: textswap-0.2.1.tar.gz
- Upload date:
- Size: 27.9 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
a992087b059ce9e7550794fb7e7f83d6fc67be9e8dde1e3766e2e8ff70a87271
|
|
| MD5 |
aadb4f2e6b746732b052bce0b15e7cb0
|
|
| BLAKE2b-256 |
66760c4df2e36116efc4e733b4c056b6d415ba9d77ec251e3571e3dac125a911
|
Provenance
The following attestation bundles were made for textswap-0.2.1.tar.gz:
Publisher:
publish.yml on cainky/textswap
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
textswap-0.2.1.tar.gz -
Subject digest:
a992087b059ce9e7550794fb7e7f83d6fc67be9e8dde1e3766e2e8ff70a87271 - Sigstore transparency entry: 896661276
- Sigstore integration time:
-
Permalink:
cainky/textswap@2325c06c9be26cfb4986748fada816267345d0d6 -
Branch / Tag:
refs/heads/main - Owner: https://github.com/cainky
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@2325c06c9be26cfb4986748fada816267345d0d6 -
Trigger Event:
workflow_dispatch
-
Statement type:
File details
Details for the file textswap-0.2.1-py3-none-any.whl.
File metadata
- Download URL: textswap-0.2.1-py3-none-any.whl
- Upload date:
- Size: 21.7 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
8cdaca962f7b36b9b1188b601dc0feca680595cbc95f44afadbd96809a0d5e00
|
|
| MD5 |
e8348873544046442660c7d721d42d06
|
|
| BLAKE2b-256 |
8715fdf5949b8af0b5332b15b36765e45a570f23cb56fcd050b7a8bf78e2d0ed
|
Provenance
The following attestation bundles were made for textswap-0.2.1-py3-none-any.whl:
Publisher:
publish.yml on cainky/textswap
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
textswap-0.2.1-py3-none-any.whl -
Subject digest:
8cdaca962f7b36b9b1188b601dc0feca680595cbc95f44afadbd96809a0d5e00 - Sigstore transparency entry: 896661300
- Sigstore integration time:
-
Permalink:
cainky/textswap@2325c06c9be26cfb4986748fada816267345d0d6 -
Branch / Tag:
refs/heads/main - Owner: https://github.com/cainky
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@2325c06c9be26cfb4986748fada816267345d0d6 -
Trigger Event:
workflow_dispatch
-
Statement type: