{"id":13745907,"url":"https://github.com/elmotec/massedit","last_synced_at":"2026-04-10T05:02:52.621Z","repository":{"id":2694673,"uuid":"3687857","full_name":"elmotec/massedit","owner":"elmotec","description":"Programmatically edit text files with Python. Useful for source to source transformations.","archived":false,"fork":false,"pushed_at":"2023-09-12T01:27:09.000Z","size":205,"stargazers_count":113,"open_issues_count":1,"forks_count":16,"subscribers_count":4,"default_branch":"main","last_synced_at":"2025-04-22T00:28:30.102Z","etag":null,"topics":["developer-tools","editor"],"latest_commit_sha":null,"homepage":"https://pypi.python.org/pypi/massedit/","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/elmotec.png","metadata":{"files":{"readme":"README.rst","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE.txt","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null}},"created_at":"2012-03-11T16:18:30.000Z","updated_at":"2024-10-12T22:24:27.000Z","dependencies_parsed_at":"2024-01-12T21:19:58.192Z","dependency_job_id":"2c2217c6-a848-49fe-80d2-ede33a30083b","html_url":"https://github.com/elmotec/massedit","commit_stats":{"total_commits":171,"total_committers":8,"mean_commits":21.375,"dds":0.5087719298245614,"last_synced_commit":"0229b40361ed6e752beb81a69f9f78d92c4906d5"},"previous_names":[],"tags_count":11,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/elmotec%2Fmassedit","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/elmotec%2Fmassedit/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/elmotec%2Fmassedit/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/elmotec%2Fmassedit/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/elmotec","download_url":"https://codeload.github.com/elmotec/massedit/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":253206065,"owners_count":21871158,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["developer-tools","editor"],"created_at":"2024-08-03T06:00:40.485Z","updated_at":"2026-04-10T05:02:52.609Z","avatar_url":"https://github.com/elmotec.png","language":"Python","readme":".. image:: https://img.shields.io/pypi/v/massedit.svg\n    :target: https://pypi.python.org/pypi/massedit/\n    :alt: PyPi version\n\n.. image:: https://img.shields.io/pypi/pyversions/massedit.svg\n    :target: https://pypi.python.org/pypi/massedit/\n    :alt: Python compatibility\n\n.. image:: https://img.shields.io/github/actions/workflow/status/elmotec/massedit/python-app.yml\n   :target: https://github.com/elmotec/massedit/actions/workflows/python-app.yml\n   :alt: GitHub Actions Workflow Status\n\n.. image:: https://img.shields.io/appveyor/ci/elmotec/massedit.svg?label=AppVeyor\n    :target: https://ci.appveyor.com/project/elmotec/massedit\n    :alt: AppVeyor status\n\n.. image:: https://img.shields.io/pypi/dm/massedit.svg\n    :alt: PyPi\n    :target: https://pypi.python.org/pypi/massedit\n\n.. image:: https://img.shields.io/librariesio/release/pypi/massedit.svg?label=libraries.io\n    :alt: Libraries.io dependency status for latest release\n    :target: https://libraries.io/pypi/massedit\n\n\n========\nmassedit\n========\n\n*formerly known as Python Mass Editor*\n\nImplements a python mass editor to process text files using Python\ncode. The modification(s) is (are) shown on stdout as a diff output. One\ncan then modify the target file(s) in place with the -w/--write option.\nThis is very similar to 2to3 tool that ships with Python 3.\n\n\n+--------------------------------------------------------------------------+\n| **WARNING**: A word of caution about the usage of ``eval()``             |\n+--------------------------------------------------------------------------+\n| This tool is useful as far as it goes but it does rely on the python     |\n| ``eval()`` function and does not check the code being executed.          |\n| **It is a major security risk** and one should not use this tool in a    |\n| production environment.                                                  |\n|                                                                          |\n| See `Ned Batchelder's article`_ for a thorough discussion of the dangers |\n| linked to ``eval()`` and ways to circumvent them. Note that None of the  |\n| counter-measure suggested in the article are implemented at this time.   |\n+--------------------------------------------------------------------------+\n\nUsage\n-----\n\nYou probably will need to know the basics of the `Python re module`_ (regular\nexpressions).\n\n::\n\n    usage: massedit.py [-h] [-V] [-w] [-v] [-e EXPRESSIONS] [-f FUNCTIONS]\n                       [-x EXECUTABLES] [-s START_DIRS] [-m MAX_DEPTH] [-o FILE]\n                       [-g FILE] [--encoding ENCODING] [--newline NEWLINE]\n                       [file pattern [file pattern ...]]\n\n    Python mass editor\n\n    positional arguments:\n      file pattern          shell-like file name patterns to process or - to read\n                            from stdin.\n\n    optional arguments:\n      -h, --help            show this help message and exit\n      -V, --version         show program's version number and exit\n      -w, --write           modify target file(s) in place. Shows diff otherwise.\n      -v, --verbose         increases log verbosity (can be specified multiple\n                            times)\n      -e EXPRESSIONS, --expression EXPRESSIONS\n                            Python expressions applied to target files. Use the\n                            line variable to reference the current line.\n      -f FUNCTIONS, --function FUNCTIONS\n                            Python function to apply to target file. Takes file\n                            content as input and yield lines. Specify function as\n                            [module]:?\u003cfunction name\u003e.\n      -x EXECUTABLES, --executable EXECUTABLES\n                            Python executable to apply to target file.\n      -s START_DIRS, --start START_DIRS\n                            Directory(ies) from which to look for targets.\n      -m MAX_DEPTH, --max-depth-level MAX_DEPTH\n                            Maximum depth when walking subdirectories.\n      -o FILE, --output FILE\n                            redirect output to a file\n      -g FILE, --generate FILE\n                            generate stub file suitable for -f option\n      --encoding ENCODING   Encoding of input and output files\n      --newline NEWLINE     Newline character for output files\n\n    Examples:\n    # Simple string substitution (-e). Will show a diff. No changes applied.\n    massedit.py -e \"re.sub('failIf', 'assertFalse', line)\" *.py\n\n    # File level modifications (-f). Overwrites the files in place (-w).\n    massedit.py -w -f fixer:fixit *.py\n\n    # Will change all test*.py in subdirectories of tests.\n    massedit.py -e \"re.sub('failIf', 'assertFalse', line)\" -s tests test*.py\n\n    # Will transform virtual methods (almost) to MOCK_METHOD suitable for gmock (see https://github.com/google/googletest).\n    massedit.py -e \"re.sub(r'\\s*virtual\\s+([\\w:\u003c\u003e,\\s\u0026*]+)\\s+(\\w+)(\\([^\\)]*\\))\\s*((\\w+)*)(=\\s*0)?;', 'MOCK_METHOD(\\g\u003c1\u003e, \\g\u003c2\u003e, \\g\u003c3\u003e, (\\g\u003c4\u003e, override));', line)\" gmock_test.cpp\n\n\nIf massedit is installed as a package (from pypi for instance), one can interact with it as a command line tool:\n\n::\n\n  python -m massedit -e \"re.sub('assertEquals', 'assertEqual', line)\" test.py\n\n\nOr as a library (command line option above to be passed as kewyord arguments):\n\n::\n\n  \u003e\u003e\u003e import massedit\n  \u003e\u003e\u003e filenames = ['massedit.py']\n  \u003e\u003e\u003e massedit.edit_files(filenames, [\"re.sub('Jerome', 'J.', line)\"])\n\n\nLastly, there is a convenient ``massedit.bat`` wrapper for Windows included in\nthe distribution.\n\n\nInstallation\n------------\n\nDownload ``massedit.py`` from ``http://github.com/elmotec/massedit`` or :\n\n::\n\n  python -m pip install massedit\n\n\nPoor man source-to-source manipulation\n--------------------------------------\n\nI find myself using massedit mostly for source to source modification of\nlarge code bases like this:\n\nFirst create a ``fixer.py`` python module with the function that will\nprocess your source code. For instance, to add a header:\n\n::\n\n  def add_header(lines, file_name):\n      yield '// This is my header'  # will be the first line of the file.\n      for line in lines:\n          yield line\n\n\nAdds the location of ``fixer.py`` to your ``$PYTHONPATH``, then simply\ncall ``massedit.py`` like this:\n\n::\n\n  massedit.py -f fixer:add_header *.h\n\n\nYou can add the ``-s .`` option to process all the ``.h`` files reccursively.\n\n\nPlans\n-----\n\n- Add support for 3rd party tool (e.g. `autopep8`_) to process the files.\n- Add support for a file of expressions as an argument to allow multiple\n  modification at once.\n- Find a satisfactory way (ie. easy to use) to handle multiline regex as the\n  current version works on a line by line basis.\n\n\nRationale\n---------\n\n- I have a hard time practicing more than a few dialects of regular\n  expressions.\n- I need something portable to Windows without being bothered by eol.\n- I believe Python is the ideal tool to build something more powerful than\n  simple regex based substitutions.\n\n\nBackground\n----------\n\nI have been using runsed and checksed (from Unix Power Tools) for years and\ndid not find a good substitute under Windows until I came across Graham\nFawcett python recipe 437932_ on ActiveState. It inspired me to write the\nmassedit.\n\nThe core was fleshed up a little, and here we are. If you find it useful and\nenhance it please, do not forget to submit patches. Thanks!\n\nIf you are more interested in awk-like tool, you probably will find pyp_ a\nbetter alternative.\n\n\nContributing\n------------\n\nTo set things up for development, please pip-install massedit as shown below.\nIt will install it in editable mode and the develop extra packages, including\ncommitizen that is recommended to have commits follow conventional commits\nconvention:\n\n::\n\n    python -m venv venv\n    . venv/bin/activate\n    python -m pip install -e .[develop,test]\n\n\nLicense\n-------\n\nLicensed under the term of `MIT License`_. See attached file LICENSE.txt.\n\n\nChanges\n-------\n\nSee CHANGELOG.md for changes later than 0.69.0\n\n0.69.1 (2023-09-10)\n  Updated infrastructure files to setup.cfg/pyproject.toml instead of\n  setup.py.  Thanks @isidroas.\n\n0.69.0 (2020-12-22)\n  Also moved CI to github workflows from travis and added\n  regression tests for Python 2.7.\n\n0.68.6 (2019-12-02)\n  Added support for Python 3.8, stdin input via - argument. Documented\n  regex to turn base classes into googlemock MOCK_METHOD.\n\n0.68.5 (2019-04-13)\n  Added --newline option to force newline output. Thanks @ALFNeT!\n\n0.68.4 (2017-10-24)\n  Fixed bug that would cause changes to be missed when the -w option is\n  ommited. Thanks @tgoodlet!\n\n0.68.3 (2017-09-20)\n  Added --generate option to quickly generate a fixer.py template file\n  to be modified to be used with -f fixer.fixit option. Added official\n  support for Python 3.6\n\n0.68.1 (2016-06-04)\n  Fixed encoding issues when processing non-ascii files.\n  Added --encoding option to force the value of the encoding if need be.\n  Listed support for Python 3.5\n\n0.67.1 (2015-06-28)\n  Documentation fixes.\n\n0.67 (2015-06-23)\n  Added file_name argument to processing functions.\n  Fixed incorrect closing of sys.stdout/stderr.\n  Improved diagnostic when the processing function does not take 2 arguments.\n  Swapped -v and -V option to be consistent with Python.\n  Pylint fixes.\n  Added support for Python 3.4.\n  Dropped support for Python 3.2.\n\n0.66 (2013-07-14)\n  Fixed lost executable bit with -f option (thanks myint).\n\n0.65 (2013-07-12)\n  Added -f option to execute code in a separate file/module. Added Travis continuous integration (thanks myint). Fixed python 2.7 support (thanks myint).\n\n0.64 (2013-06-01)\n  Fixed setup.py so that massedit installs as a script. Fixed eol issues (thanks myint).\n\n0.63 (2013-05-27)\n  Renamed to massedit. Previous version are still known as Python-Mass-Editor.\n\n0.62 (2013-04-11)\n  Fixed bug that caused an EditorError to be raised when the result of the\n  expression is an empty string.\n\n0.61 (2012-07-06)\n  Added massedit.edit_files function to ease usage as library instead of as\n  a command line tool (suggested by Maxim Veksler).\n\n0.60 (2012-07-04)\n  Treats arguments as patterns rather than files to ease processing of\n  multiple files in multiple subdirectories.  Added -s (start directory)\n  and -m (max depth) options.\n\n0.52 (2012-06-05)\n  Upgraded for python 3. Still compatible with python 2.7.\n\n0.51 (2012-05)\n  Initial release (Beta).\n\n\nContributor acknowledgement\n---------------------------\n\nhttps://github.com/myint\nhttps://github.com/tgoodlet\nhttps://github.com/ALFNeT\nhttps://github.com/isidroas\n\n\n\n.. _437932: http://code.activestate.com/recipes/437932-pyline-a-grep-like-sed-like-command-line-tool/\n.. _Python re module: http://docs.python.org/library/re.html\n.. _Pyp: http://code.google.com/p/pyp/\n.. _MIT License: http://en.wikipedia.org/wiki/MIT_License\n.. _autopep8: http://pypi.python.org/pypi/autopep8\n.. _Ned Batchelder's article: http://nedbatchelder.com/blog/201206/eval_really_is_dangerous.html\n.. _commitizen: https://commitizen-tools.github.io/commitizen/\n","funding_links":[],"categories":["Libraries and refactoring","Code Refactoring"],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Felmotec%2Fmassedit","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Felmotec%2Fmassedit","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Felmotec%2Fmassedit/lists"}