{ "info": { "author": "Robert Kern", "author_email": "robert.kern@enthought.com", "bugtrack_url": null, "classifiers": [ "Development Status :: 5 - Production/Stable", "Environment :: Console", "Intended Audience :: Developers", "License :: OSI Approved :: BSD License", "Operating System :: OS Independent", "Programming Language :: Python", "Programming Language :: Python :: 3", "Programming Language :: Python :: 3.5", "Programming Language :: Python :: 3.6", "Programming Language :: Python :: 3.7", "Topic :: Utilities" ], "description": "====\ngrin\n====\n\n[this is a port of original grin to python3]\n\nI wrote grin to help me search directories full of source code. The venerable\nGNU grep_ and find_ are great tools, but they fall just a little short for my\nnormal use cases.\n\nThe main problem I had with GNU grep_ is that I had no way to exclude certain\ndirectories that I knew had nothing of interest for me, like .svn/, CVS/ and\nbuild/. The results from those directories obscured the results I was actually\ninterested in. There are tools like ack_, which skip these directories, but ack_\nalso only grepped files with extensions that it knew about. Furthermore, it had\nnot implemented the context lines feature, which I had grown accustomed to.\nRecent development has added these features, but I had already released grin by\nthe time I found out.\n\nOne can construct a GNU find_ command that will exclude .svn/ and the rest, but\nthe only reliable way I am aware of runs grep_ on each file independently. The\nstartup cost of invoking many separate grep_ processes is relatively large.\n\nAlso, I was bored. It seems to be catching. Perl has ack_, Ruby has rak_, and\nnow Python has grin.\n\nI wrote grin to get exactly the features I wanted:\n\n * Recurse directories by default.\n * Do not go into directories with specified names.\n * Do not search files with specified extensions.\n * Be able to show context lines before and after matched lines.\n * Python regex syntax (one can quibble as to whether this is a feature or my\n laziness for using the regex library provided with my implementation\n language, but as a Python programmer, this is the syntax I am most familiar\n with).\n * Unless suppressed via a command line option, display the filename regardless\n of the number of files.\n * Accept a file (or stdin) with a list of newline-separated filenames. This\n allows one to use find_ to feed grin a list of filenames which might have\n embedded spaces quite easily.\n * Grep through gzipped text files.\n * Be useful as a library to build custom tools quickly.\n\nI have also exposed the directory recursion logic as the command-line tool\n\"grind\" in homage to find_. It will recurse through directories matching a glob\npattern to file names and printing out the matches. It shares the directory and\nfile extension skipping settings that grin uses.\n\nFor configuration, you can specify the environment variables GRIN_ARGS and\nGRIND_ARGS. These should just contain command-line options of their respective\nprograms. These will be prepended to the command-line arguments actually given.\nOptions given later will override options given earlier, so all options\nexplicitly in the command-line will override those in the environment variable.\nFor example, if I want to default to two lines of context and no skipped\ndirectories, I would have this line in my bashrc::\n\n export GRIN_ARGS=\"-C 2 --no-skip-dirs\"\n\n.. _grep : http://www.gnu.org/software/grep/\n.. _ack : http://search.cpan.org/~petdance/ack/ack\n.. _rak: http://rak.rubyforge.org/\n.. _find : http://www.gnu.org/software/findutils/\n\n\nInstallation\n------------\n\nInstall using pip_::\n\n $ python3 -m pip install grin3\n\nRunning the tests::\n\n $ python3 -m unittest discover tests\n ----------------------------------------------------------------------\n Ran 24 tests in 0.010s\n\n OK\n\n\nThere is one little tweak to the installation that you may want to consider. By\ndefault, setuptools installs scripts indirectly; the scripts installed to\n$prefix/bin or Python3x\\Scripts use setuptools' pkg_resources module to load\nthe exact version of grin egg that installed the script, then runs the script's\nmain() function. This is not usually a bad feature, but it can add substantial\nstartup overhead for a small command-line utility like grin. If you want the\nresponse of grin to be snappier, I recommend installing custom scripts that just\nimport the grin module and run the appropriate main() function. See the files\nexamples/grin and examples/grind for examples.\n\n.. _pip : https://pip.pypa.io/en/stable/\n\n\nUsing grin\n----------\n\nTo recursively search the current directory for a regex::\n\n $ grin some_regex\n\nTo search an explicit set of files::\n\n $ grin some_regex file1.txt path/to/file2.txt\n\nTo recursively search an explicit set of directories::\n\n $ grin some_regex dir1/ dir2/\n\nTo search data piped to stdin::\n\n $ cat somefile | grin some_regex -\n\nTo make the regex case-insensitive::\n\n $ grin -i some_regex\n\nTo output 2 lines of context before, after, or both before and after the\nmatches::\n\n $ grin -B 2 some_regex\n $ grin -A 2 some_regex\n $ grin -C 2 some_regex\n\nTo only search Python .py files::\n\n $ grin -I \"*.py\" some_regex\n\nTo suppress the line numbers which are printed by default::\n\n $ grin -N some_regex\n\nTo just show the names of the files that contain matches rather than the matches\nthemselves::\n\n $ grin -l some_regex\n\nTo suppress the use of color highlighting::\n\n # Note that grin does its best to only use color when it detects that it is\n # outputting to a real terminal. If the output is being piped to a file or\n # a pager, then no color will be used.\n $ grin --no-color some_regex\n\nTo force the use of color highlighting when piping the output to something that\nis capable of understanding ANSI color escapes::\n\n $ grin --force-color some_regex | less -R\n\nTo avoid recursing into directories named either CVS or RCS::\n\n $ grin -d CVS,RCS some_regex\n\nBy default grin skips a large number of files. To suppress all of this behavior\nand search everything::\n\n $ grin -sbSDE some_regex\n\nTo search for files newer than some_file.txt::\n\n # If no subdirectory or file in the list contains whitespace:\n $ grin some_regex `find . -newer some_file.txt`\n\n # If a subdirectory or file in the list may contain whitespace:\n $ find . -newer some_file.txt | grin -f - some_regex\n\n\nUsing grind\n-----------\n\nTo find files matching the glob \"foo*.py\" in this directory or any subdirectory\nusing same the default rules as grin::\n\n $ grind \"foo*.py\"\n\nTo suppress all of the default rules and not skip any files or directories while\nsearching::\n\n $ grind -sbSDE \"foo*.py\"\n\nTo find all files that are not skipped by the default rules::\n\n $ grind\n\nTo start the search in a particular set of directories instead of the current\none (not the -- separator)::\n\n $ grind --dirs thisdir that/dir -- \"foo*.py\"\n\n\nUsing grin as a Library\n-----------------------\n\nOne of the goals I had when writing grin was to be able to use it as a library\nto write custom tools. You can see one example that I quickly hacked up in\nexamples/grinimports.py . It reuses almost all of grin's infrastructure, except\nthat it preprocesses Python files to extract and normalize just the import\nstatements. This lets you conveniently and robustly search for import\nstatements. Look at \"grinimports.py --help\" for more information.\n\nexamples/grinpython.py allows you to search through Python files and specify whether you want to search through actual Python code, comments or string literals in any combination. For example::\n\n $ grinpython.py -i --strings grep grin.py\n grin.py:\n 188 : \"\"\" Grep a single file for a regex by iterating over the lines in a file.\n 292 : \"\"\" Do a full grep.\n ...\n\n $ grinpython.py -i --comments grep grin.py\n grin.py:\n 979 : # something we want to grep.\n\n $ grinpython.py -i --python-code grep grin.py\n grin.py:\n 187 : class GrepText:\n 291 : def do_grep(self, fp):\n ...\n\nSimilarly, it should be straightforward to write small tools like this which\nextract and search text metadata from binary files.\n\n\nDevelopment, bugs and such\n--------------------------\n\nThe development sources are hosted on Bitbucket (in mercurial format):\n\n https://bitbucket.org/rsalmaso/grin3\n\nand in git mirrors on\n\n https://github.com/rsalmaso/grin3\n\n https://gitlab.com/rsalmaso/grin3\n\nYou are free to open a PR/MR/Bug where you want.\n\nThe source code is formatted with `black_`, `isort_` and `flake8_`\n\n.. _black : https://pypi.org/project/black/\n.. _isort : https://pypi.org/project/isort/\n.. _flake8 : https://pypi.org/project/flake8/\n\n\nTesting\n-------\n\ntests\n~~~~~\n\nRunning unittests::\n\n $ python3 -m unittest discover tests\n ----------------------------------------------------------------------\n Ran 24 tests in 0.010s\n\n OK\n\ntox\n~~~\n\nRun all tests into dedicated virtualenvs, and check code style.\n\nvagrant\n~~~~~~~\n\nThere is a simple vagrant config to install a preconfigured system with everything needed to run tests locally.\n\nJust run::\n\n $ vagrant up\n # and wait for provisioning\n $ vagrant ssh\n $ tox -e ALL\n\nIt will run all tests suite on all supported python versions\n\n\nTo Do\n-----\n\n* Figure out the story for grepping UTF-8, UTF-16 and UTF-32 Unicode text files.\n\n\n", "description_content_type": "", "docs_url": null, "download_url": "", "downloads": { "last_day": -1, "last_month": -1, "last_week": -1 }, "home_page": "https://bitbucket.org/rsalmaso/grin3", "keywords": "", "license": "BSD", "maintainer": "Raffaele Salmaso", "maintainer_email": "raffaele@salmaso.org", "name": "grin3", "package_url": "https://pypi.org/project/grin3/", "platform": "", "project_url": "https://pypi.org/project/grin3/", "project_urls": { "Homepage": "https://bitbucket.org/rsalmaso/grin3" }, "release_url": "https://pypi.org/project/grin3/2.0.2/", "requires_dist": null, "requires_python": "", "summary": "A grep program configured the way I like it. (python3 port)", "version": "2.0.2" }, "last_serial": 5689597, "releases": { "1.2.3": [ { "comment_text": "", "digests": { "md5": "3ab66f79fb2c05635b004530e84f5c7c", "sha256": "6be9153e1b007e40311406fe057f0edccbe64d33db8a6ec523c2629623ba0476" }, "downloads": -1, "filename": "grin3-1.2.3-py3-none-any.whl", "has_sig": false, "md5_digest": "3ab66f79fb2c05635b004530e84f5c7c", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 20857, "upload_time": "2017-04-20T09:16:35", "url": "https://files.pythonhosted.org/packages/67/33/c077c8db6606e6fefd56a9cbdaa8f4808b80538bc5e266c500d2ddba0a22/grin3-1.2.3-py3-none-any.whl" } ], "2.0": [ { "comment_text": "", "digests": { "md5": "b7d0a8dbeddf3a170ff769610db49a6e", "sha256": "5de8b7e1e5842a11cac5039d1b4f1214ed1007b9411efd4ae06e1dc26d574796" }, "downloads": -1, "filename": "grin3-2.0-py3-none-any.whl", "has_sig": false, "md5_digest": "b7d0a8dbeddf3a170ff769610db49a6e", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 5779, "upload_time": "2019-08-14T21:42:00", "url": "https://files.pythonhosted.org/packages/04/75/e71ab1bb1cb0d00ef519750695537a44a2923688b18b403159384b228415/grin3-2.0-py3-none-any.whl" } ], "2.0.1": [ { "comment_text": "", "digests": { "md5": "3dab9bd0815dd52305f295a28b578b7b", "sha256": "5e66967a9935d9c16153b0ac987b29a7e1c9be6b25b9fdeac989b27545af686e" }, "downloads": -1, "filename": "grin3-2.0.1-py3-none-any.whl", "has_sig": false, "md5_digest": "3dab9bd0815dd52305f295a28b578b7b", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 28557, "upload_time": "2019-08-15T17:27:16", "url": "https://files.pythonhosted.org/packages/40/69/9074d4fa0f823504691b029cbd60d1b9d245ebf2cbd259d008cefc954e8c/grin3-2.0.1-py3-none-any.whl" } ], "2.0.2": [ { "comment_text": "", "digests": { "md5": "ae8cd2412623c14704bfe2b2317f362d", "sha256": "e18742160b5cef801f56a2cf26a37a4624e71c5835a8bac27c42aa0945c1c82b" }, "downloads": -1, "filename": "grin3-2.0.2-py3-none-any.whl", "has_sig": false, "md5_digest": "ae8cd2412623c14704bfe2b2317f362d", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 28559, "upload_time": "2019-08-16T21:34:05", "url": "https://files.pythonhosted.org/packages/85/79/82a7e76de97b58b3eb115ef9f502e1b1ff28387085d309412183fd475cf0/grin3-2.0.2-py3-none-any.whl" } ] }, "urls": [ { "comment_text": "", "digests": { "md5": "ae8cd2412623c14704bfe2b2317f362d", "sha256": "e18742160b5cef801f56a2cf26a37a4624e71c5835a8bac27c42aa0945c1c82b" }, "downloads": -1, "filename": "grin3-2.0.2-py3-none-any.whl", "has_sig": false, "md5_digest": "ae8cd2412623c14704bfe2b2317f362d", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 28559, "upload_time": "2019-08-16T21:34:05", "url": "https://files.pythonhosted.org/packages/85/79/82a7e76de97b58b3eb115ef9f502e1b1ff28387085d309412183fd475cf0/grin3-2.0.2-py3-none-any.whl" } ] }