Skip to content

Instantly share code, notes, and snippets.

@amitsaha
Created September 21, 2012 01:20
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save amitsaha/3759263 to your computer and use it in GitHub Desktop.
Save amitsaha/3759263 to your computer and use it in GitHub Desktop.
File finding Utility
#!/usr/bin/env python
"""myfind
Usage:
myfind.py [--directory=<dir>] [--pattern=<p>] [--text=<text>]
myfind.py -h | --help
myfind.py --version
Examples:
myfind.py
lists all files in the current directory
myfind.py --directory='/home/gene' --pattern='*.py'
lists all .py files in /home/gene
myfind.py --directory='/home/gene' --pattern='*.py' --text='spam''
lists all .py files in /home/gene containing the text spam
Options:
-h --help Show this screen.
--directory=<dir> Directory to start searching (default: .)
--pattern=<p> Files to look for (default: *.*)
--text=<text> Text to search for (default: 'None')
"""
from docopt import docopt
import os
import fnmatch
# do the walk
def walk(starthere, lookfor):
for (root, dirs, files) in os.walk(starthere,followlinks=True):
for fname in files:
if fnmatch.fnmatch(fname,lookfor):
yield(os.path.realpath(os.path.join(root,fname)))
if __name__ == '__main__':
arguments = docopt(__doc__, version='myfind v0.001')
if arguments['--directory']:
starthere = os.path.abspath(arguments['--directory'])
else:
starthere = '.'
if arguments['--pattern']:
lookfor = arguments['--pattern']
else:
lookfor = '*'
if arguments['--text']:
text = arguments['--text']
else:
text = None
for filename in walk(starthere,lookfor):
if text is not None:
try:
with open(filename,'r') as f:
if text in f.read():
print filename
except IOError:
# permission/link followup failure, etc
pass
else:
print filename
@keleshev
Copy link

Note, that syntax for defaults should use square brackets—[default: *.*], not (default: *.*).

@Newky
Copy link

Newky commented Nov 21, 2012

Hey,

You recently wrote a response to my linux journal article (which I will respond to at some point very soon when I get a minute)

Thought I would write some alternatives to what your program is doing but first let me say something else. This seems like a really nice effort and is a perfectly valid way to solve the problem.

so for the use cases u list in the source:

myfind.py --> ls
myfind.py --directory='/home/gene' --pattern='.py' --> ls *.py
myfind.py --directory='/home/gene' --pattern='
.py' --text='spam'' --> grep -r "spam" *.py

Often a good grounding in the various gnu utilitys such as cat, head, tail, grep and even some sed can come in very handy.

Keep up the good work.

@Newky
Copy link

Newky commented Nov 21, 2012

There was a problem with the formatting of the previous comment,

the second example should read:
myfind.py --directory='/home/gene' --pattern='_.py' --> ls _.py

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment