Compare commits

..

No commits in common. "5136ddf27f67065de0f4bb893043b0a466664452" and "5cbf98a926cf4e28f589ed2e0cee4cb85fd5b17b" have entirely different histories.

2 changed files with 37 additions and 71 deletions

View File

@ -1,6 +1,5 @@
# Bulk String Replacer # bulk-string-replacer
bulk-string-replacer is a tool designed to traverse directories and perform bulk string replacement in filenames, folder names, and file contents. Whether you want to target hidden items, preview changes before execution, or recursively navigate through folders, this versatile utility has you covered.
`bulk-string-replacer` is a Python-based command-line utility that allows for comprehensive search and replacement operations within file and folder names, as well as within file contents across specified directories. It's designed to handle bulk updates quickly and efficiently, with support for recursive directory traversal, hidden files, and a preview mode to review changes before they're applied.
## Author ## Author
@ -8,63 +7,39 @@ Kevin Veen-Birkenbach
- 📧 Email: [kevin@veen.world](mailto:kevin@veen.world) - 📧 Email: [kevin@veen.world](mailto:kevin@veen.world)
- 🌍 Website: [https://www.veen.world/](https://www.veen.world/) - 🌍 Website: [https://www.veen.world/](https://www.veen.world/)
## Background ## Link to Original Conversation
Learn more about the development and use cases of this tool in the [original conversation with the developer](https://chat.openai.com/share/cfdbc008-8374-47f8-8853-2e00ee27c959). For more context on how this tool was developed, you can [view the original conversation here](https://chat.openai.com/share/8567c240-3905-4521-b30e-04104015bb9b).
## Getting Started ## Setup and Usage
### Prerequisites
- Python 3.x
- Access to a command-line interface
### Installation
Clone the repository to your local machine:
1. Clone the repository:
```bash ```bash
git clone https://github.com/kevinveenbirkenbach/bulk-string-replacer.git git clone https://github.com/kevinveenbirkenbach/bulk-string-replacer.git
``` ```
Change into the project directory: 2. Navigate to the cloned directory:
```bash ```bash
cd bulk-string-replacer cd bulk-string-replacer
``` ```
### Usage 3. Run the script with Python:
Run the script with Python, specifying your target paths, the string to be replaced, and the new string:
```bash ```bash
python replace_string.py old_string --new-string new_string_value --options paths... python replace_string.py [path] [old_string] [new_string] [options]
``` ```
#### Options ### Options:
- `old_string`: The string you want to search for and replace. - `--recursive`: Replace in all subdirectories and files.
- `--new-string`: The string that will replace `old_string`. Defaults to an empty string if not specified. - `--folder`: Replace in folder names.
- `--recursive`: Recursively process all subdirectories and files within the given paths. - `--files`: Replace in file names.
- `--folder`: Replace string occurrences within folder names. - `--content`: Replace inside file contents.
- `--files`: Replace string occurrences within file names. - `--preview`: Preview changes without making actual replacements.
- `--content`: Replace string occurrences within the contents of the files. - `--verbose`: Verbose mode - view detailed outputs.
- `--preview`: Preview changes without applying them. No files will be modified. - `--hidden`: Target hidden files and folders.
- `--verbose`: Output detailed information during the execution of the script.
- `--hidden`: Include hidden files and directories in the operation.
Paths are specified at the end of the command, separated by spaces. For example: For more detailed options, refer to the inline script help or the aforementioned conversation.
```bash
python replace_string.py "search_string" --new-string "replacement_string" --recursive --verbose /path/to/first/directory /path/to/second/directory
```
Replace `/path/to/first/directory` and `/path/to/second/directory` with the actual paths you want to process.
## Contributions
Contributions are welcome! Please feel free to submit a pull request or open an issue on the GitHub repository.
## License ## License
This project is open-sourced under the GNU Affero General Public License v3.0. See the `LICENSE` file for more details. This project is licensed under the GNU Affero General Public License v3.0. The full license text is available in the `LICENSE` file of this repository.

View File

@ -8,17 +8,13 @@ def replace_content(path, old_string, new_string, preview, verbose):
if old_string in content: if old_string in content:
new_content = content.replace(old_string, new_string) new_content = content.replace(old_string, new_string)
print_verbose(f"Replacing content in: {path}",verbose) if verbose:
print(f"Replacing content in: {path}")
if not preview: if not preview:
with open(path, 'w', encoding='utf-8') as f: with open(path, 'w', encoding='utf-8') as f:
f.write(new_content) f.write(new_content)
def print_verbose(content,verbose):
if verbose:
print(content)
def process_directory(base_path, old_string, new_string, recursive, folder, files, content, preview, verbose, hidden): def process_directory(base_path, old_string, new_string, recursive, folder, files, content, preview, verbose, hidden):
# Eine Liste, um die Pfade der umzubenennenden Ordner zu speichern # Eine Liste, um die Pfade der umzubenennenden Ordner zu speichern
directories_to_rename = [] directories_to_rename = []
@ -38,7 +34,8 @@ def process_directory(base_path, old_string, new_string, recursive, folder, file
if old_string in f: if old_string in f:
old_path = os.path.join(root, f) old_path = os.path.join(root, f)
new_path = os.path.join(root, f.replace(old_string, new_string)) new_path = os.path.join(root, f.replace(old_string, new_string))
print_verbose(f"Renaming file from: {old_path} to: {new_path}",verbose) if verbose:
print(f"Renaming file from: {old_path} to: {new_path}")
if not preview: if not preview:
os.rename(old_path, new_path) os.rename(old_path, new_path)
@ -55,15 +52,16 @@ def process_directory(base_path, old_string, new_string, recursive, folder, file
# Ordnernamen ändern nach dem os.walk() Durchlauf # Ordnernamen ändern nach dem os.walk() Durchlauf
for old_path, new_path in directories_to_rename: for old_path, new_path in directories_to_rename:
verbose(f"Renaming directory from: {old_path} to: {new_path}") if verbose:
print(f"Renaming directory from: {old_path} to: {new_path}")
if not preview: if not preview:
os.rename(old_path, new_path) os.rename(old_path, new_path)
def main(): def main():
parser = argparse.ArgumentParser(description="Replace strings in directories and files.") parser = argparse.ArgumentParser(description="Replace strings in directories and files.")
parser.add_argument('paths', nargs='+', help="Paths in which replacements should be made.") parser.add_argument('path', help="Path in which replacements should be made.")
parser.add_argument('old_string', help="The string to be replaced.") parser.add_argument('old_string', help="The string to be replaced.")
parser.add_argument('--new-string', dest='new_string', default="", help="The string to replace with. Default is empty string.") parser.add_argument('new_string', nargs='?', default="", help="The string to replace with. Default is empty string.")
parser.add_argument('--recursive', action='store_true', help="Replace in all subdirectories and files.") parser.add_argument('--recursive', action='store_true', help="Replace in all subdirectories and files.")
parser.add_argument('--folder', action='store_true', help="Replace in folder names.") parser.add_argument('--folder', action='store_true', help="Replace in folder names.")
parser.add_argument('--files', action='store_true', help="Replace in file names.") parser.add_argument('--files', action='store_true', help="Replace in file names.")
@ -71,16 +69,9 @@ def main():
parser.add_argument('--preview', action='store_true', help="Preview changes without replacing.") parser.add_argument('--preview', action='store_true', help="Preview changes without replacing.")
parser.add_argument('--verbose', action='store_true', help="Verbose mode.") parser.add_argument('--verbose', action='store_true', help="Verbose mode.")
parser.add_argument('--hidden', action='store_true', help="Apply to hidden files and folders.") parser.add_argument('--hidden', action='store_true', help="Apply to hidden files and folders.")
args = parser.parse_args() args = parser.parse_args()
# Use os.path.expanduser to expand the tilde to the home directory process_directory(args.path, args.old_string, args.new_string, args.recursive, args.folder, args.files, args.content, args.preview, args.verbose, args.hidden)
expanded_paths = [os.path.expanduser(path) for path in args.paths]
for path in expanded_paths:
print_verbose(f"Replacing in path: {path}",args.verbose)
process_directory(path, args.old_string, args.new_string, args.recursive, args.folder, args.files, args.content, args.preview, args.verbose, args.hidden)
if __name__ == "__main__": if __name__ == "__main__":
main() main()