{ "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", "Topic :: Utilities" ], "description": "====\ngrin\n====\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\ngrin uses setuptools_ to find and install its dependency on argparse_. grin is\neasy_installable::\n\n $ easy_install grin\n\nAlternatively, download and unpack the tarball and install::\n\n $ tar zxf grin-1.2.tar.gz\n $ python setup.py install\n\nOn UNIX systems, use sudo for the latter command if you need to install the\nscripts to a directory that requires root privileges::\n\n $ sudo python setup.py install\n\nRunning the unittests requires the nose_ framework, which can also be\neasy_installed::\n\n $ easy_install \"nose >= 0.10\"\n ...\n $ nosetests \n .........................\n ----------------------------------------------------------------------\n Ran 25 tests in 0.192s\n\n OK\n $ python setup.py test # The other way to run the tests.\n running test\n ... etc.\n\nThe development Subversion repository can be checked out anonymously::\n\n $ svn co https://svn.enthought.com/svn/sandbox/grin/trunk/ grin\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 Python2x\\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.. _setuptools : http://pypi.python.org/pypi/setuptools\n.. _argparse : http://argparse.python-hosting.com\n.. _nose : http://www.somethingaboutorange.com/mrl/projects/nose\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(object):\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\nTo Do\n-----\n\n* Figure out the story for grepping UTF-8, UTF-16 and UTF-32 Unicode text files.\n\n\nBugs and Such\n-------------\n\nIf you find a bug, or a missing feature you really want added, please post to\nthe enthought-dev_ mailing list or email the author at\n.\n\n.. _enthought-dev : https://mail.enthought.com/mailman/listinfo/enthought-dev", "description_content_type": null, "docs_url": null, "download_url": "UNKNOWN", "downloads": { "last_day": -1, "last_month": -1, "last_week": -1 }, "home_page": "UNKNOWN", "keywords": null, "license": "BSD", "maintainer": null, "maintainer_email": null, "name": "grin", "package_url": "https://pypi.org/project/grin/", "platform": "UNKNOWN", "project_url": "https://pypi.org/project/grin/", "project_urls": { "Download": "UNKNOWN", "Homepage": "UNKNOWN" }, "release_url": "https://pypi.org/project/grin/1.2.1/", "requires_dist": null, "requires_python": null, "summary": "A grep program configured the way I like it.", "version": "1.2.1" }, "last_serial": 738982, "releases": { "1.1": [ { "comment_text": "", "digests": { "md5": "1c6e4d3a785175a8a9a7ab11dde181b8", "sha256": "c9387eea3f9c59369cc34779bbb8dfb01319741c2094c61cb8bacb90d90c5d6e" }, "downloads": -1, "filename": "grin-1.1.tar.gz", "has_sig": false, "md5_digest": "1c6e4d3a785175a8a9a7ab11dde181b8", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 21873, "upload_time": "2008-07-14T04:41:01", "url": "https://files.pythonhosted.org/packages/47/0c/d87f348e96edff22dbcad4c56e278d0ba81a2d881fdfeb3641978e518f31/grin-1.1.tar.gz" } ], "1.1.1": [ { "comment_text": "", "digests": { "md5": "9dca5a5876938adfd9dfc20869818660", "sha256": "4ed6f98e0c6e96b8cd47efb861005e5330790b2ddaf44b46e852438f7897ab42" }, "downloads": -1, "filename": "grin-1.1.1.tar.gz", "has_sig": false, "md5_digest": "9dca5a5876938adfd9dfc20869818660", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 22356, "upload_time": "2008-08-15T05:33:59", "url": "https://files.pythonhosted.org/packages/88/dc/d7d3193588256b1c7e884caf1771c1f12f8a57c4175c82f2526e2ced56e3/grin-1.1.1.tar.gz" } ], "1.2": [ { "comment_text": "", "digests": { "md5": "8fd1294ecebcc123233d654cf894bf5c", "sha256": "410e84e1a6447686ea38d1d032dde57cca2843f259c102516057def4b0c0e7ae" }, "downloads": -1, "filename": "grin-1.2.tar.gz", "has_sig": false, "md5_digest": "8fd1294ecebcc123233d654cf894bf5c", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 26416, "upload_time": "2010-08-02T00:54:56", "url": "https://files.pythonhosted.org/packages/89/2a/192bc13047f3e7530c344717923150575b66fa5d6082abbb38fead6b76ad/grin-1.2.tar.gz" } ], "1.2.1": [ { "comment_text": "", "digests": { "md5": "d894426dfbf70bc105388c2a51348199", "sha256": "bf39303bc563c4f365365b5ff32e219dc2530a4469b7af25aa6a457ec2e29feb" }, "downloads": -1, "filename": "grin-1.2.1.tar.gz", "has_sig": false, "md5_digest": "d894426dfbf70bc105388c2a51348199", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 26854, "upload_time": "2010-10-25T00:57:01", "url": "https://files.pythonhosted.org/packages/42/9c/0b6c7912cbd9aa721e4ba614b6ced28fd1264be2259ff7461be7b569a7f8/grin-1.2.1.tar.gz" } ] }, "urls": [ { "comment_text": "", "digests": { "md5": "d894426dfbf70bc105388c2a51348199", "sha256": "bf39303bc563c4f365365b5ff32e219dc2530a4469b7af25aa6a457ec2e29feb" }, "downloads": -1, "filename": "grin-1.2.1.tar.gz", "has_sig": false, "md5_digest": "d894426dfbf70bc105388c2a51348199", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 26854, "upload_time": "2010-10-25T00:57:01", "url": "https://files.pythonhosted.org/packages/42/9c/0b6c7912cbd9aa721e4ba614b6ced28fd1264be2259ff7461be7b569a7f8/grin-1.2.1.tar.gz" } ] }