Skip to content

Instantly share code, notes, and snippets.

@scottwb
Created December 1, 2009 11:45
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 scottwb/246240 to your computer and use it in GitHub Desktop.
Save scottwb/246240 to your computer and use it in GitHub Desktop.
Find a string in configured set of dirs and files.
#!/usr/bin/env ruby
#
# Script to search for a string in a set of configured dirs. The main
# value of this is to provide:
#
# * Easy configuration for a common set of directories you like to
# grep through, and the file patterns to match per directory.
#
# * Easy configuration for the common grep options you like to use.
#
# * Automatically prefix dir greps with removal of files like
# the emacs ~ files.
#
# This script assumes you are invoking this from a shell like
# bash or zsh that supports the ** glob, and that you have grep installed.
#
###############################################################################
# Usage
###############################################################################
usage=<<EOT
Usage:
findstr.rb <string>
<string>: The string to find in the configured set of directories.
EOT
###############################################################################
# Configuration
###############################################################################
# The grep options you prefer.
GREP_OPTS = "-li"
# Configure the dirs you want want to recursively search.
DIRS = [
{:path => 'app', :patterns => ["*.*"]},
{:path => 'lib', :patterns => ["*.*"]},
{:path => 'public/javascripts', :patterns => ["*.*"]},
{:path => 'public/stylesheets', :patterns => ["*.*"]},
{:path => 'public/config', :patterns => ["*.*"]},
{:path => 'script', :patterns => ["*"]},
{:path => 'config', :patterns => ["*.*"]},
{:path => 'test', :patterns => ["*.*"]},
{:path => 'db/migrate', :patterns => ["*.*"]},
]
# Configure the patterns for kinds of files to remove.
RM_PATTERNS = [
'*~'
]
# Commands that are required for this script.
REQUIRED_CMDS = [
'grep',
]
###############################################################################
# Helpers
###############################################################################
# Runs a command in a sub-shell. Mainly used to eat stout/stderr that
# comes from the shell, not the command (e.g.: nothing matches glob).
def subshell_cmd(cmd, redirs=[])
system("#{ENV['SHELL']} -c \"#{cmd.gsub('"', '\\"')}\" #{redirs.to_a.join(' ')}")
end
###############################################################################
# Main Program
###############################################################################
if ARGV.size != 1
puts usage
exit -1
end
search_term = ARGV[0]
# Check for required command availability.
REQUIRED_CMDS.each do |cmd|
if !system("which #{cmd} > /dev/null")
puts "ERROR: You must have #{cmd} installed in your path."
puts usage
exit -1
end
end
# Before we search, remove all emacs temp files.
DIRS.each do |dir|
RM_PATTERNS.each do |pat|
subshell_cmd("rm -f #{dir[:path].gsub(' ', '\\ ')}/**/#{pat}", "&>/dev/null")
end
end
# Make a list of grep input files.
files = DIRS.map do |dir|
dir[:patterns].map do |pat|
"#{dir[:path].gsub(' ', '\\ ')}/**/#{pat}"
end.join(' ')
end.join(' ')
# Grep for what we want.
subshell_cmd("grep #{GREP_OPTS} \"#{search_term}\" #{files}")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment