Skip to content
Permalink
main
Switch branches/tags

Name already in use

A tag already exists with the provided branch name. Many Git commands accept both tag and branch names, so creating this branch may cause unexpected behavior. Are you sure you want to create this branch?
Go to file
 
 
Cannot retrieve contributors at this time
executable file 209 lines (180 sloc) 5.91 KB
#!/usr/bin/python
from __future__ import print_function
#-----------------------------------------------------------------------
# Imports
#-----------------------------------------------------------------------
import sys
import getopt
#-----------------------------------------------------------------------
# Functions
#-----------------------------------------------------------------------
def Usage(msg=None):
print("""
cgrep -iknq <str> <file>
cgrep -f <str_file> <file>
Search for matching 'clauses' in file. Clause is a block
of text separated by blank lines.
-f <str_file> Read strings from file.
-i Ignore case.
-k <key> Match <str> to entire value of <key> field.
-n Print line numbers.
-q Only print the first matching clause.
-v Print non-matching clauses.
-S Print output "KEY=VALUE\nKEY=VALUE" to set value in shell.
Run like: eval $(cgrep -k KEY VALSTR)
""")
if msg: print(msg)
raise SystemExit
# Read clauses
def read_clauses(files,lower_case=False):
line_no = 0
for file in files:
clause = []
# Open file
if file=="-":
fin = sys.stdin
else:
fin = open(file,"r")
for line in fin.readlines():
line_no += 1
line = line.strip()
# End of clause
if not line:
if clause:
yield clause
clause = []
# Add line to clause
else:
if lower_case:
clause.append((line_no, line.lower()))
else:
clause.append((line_no, line))
# Close file
if not file=="-":
fin.close()
# return last clause in file
if clause:
yield clause
clause = []
def in_search_strings(val, search_strings, ignore_case=False):
if ignore_case:
return val.lower() in [s.lower() for s in search_strings]
else:
return val in [s for s in search_strings]
# Escape shell text strings so that we can still assign them to shell
# variables even if they contain: single quotes, double quotes, and/or spaces
def escape_shell_line(line):
# Return escaped string if it contains: single quote, double quote, or
# space
for c in line:
if c in (""" '" """):
return '"' + line.replace('"','\\"') + '"'
# Return original string
return line
# Read line like "LABEL: value" and return "LABEL=value"
# so string can be used by Unix shell to set shell variable
def get_kvformat(line):
# Get first split char
for pos, character in enumerate(line):
found = character in (' ',':')
if found: break
if found:
k = line[:pos]
v = line[pos+1:].strip()
return k + '=' + escape_shell_line(v)
else:
return line
#-----------------------------------------------------------------------
# Main
#-----------------------------------------------------------------------
# Initialize options
string_file = None
search_key = None
ignore_case = False
print_line_numbers = False
quiet = False
exclude = False
versbose = False
setvars = False
# Read options
opts, args = getopt.getopt(sys.argv[1:],"f:ik:nqvS")
for key,val in opts:
if key=='-f':
string_file = val
elif key=='-k':
search_key = val
elif key=='-i':
ignore_case = True
elif key=='-n':
print_line_numbers = True
elif key=='q':
quiet = True
elif key=='-v':
exclude = True
elif key=='-S':
setvars = True
# If not string_file, then read single search string from input line
if not string_file:
if len(args)<2:
Usage()
search_string, files = args[0], args[1:]
else:
if len(args)<1:
Usage()
files = args
# Get search strings from file
if string_file:
search_strings = []
fin = open(string_file,"r")
for line in fin.readlines():
line = line.strip()
if line:
search_strings.append(line)
else:
search_strings = (search_string,)
# If ignoring cause, convert all search strings to lowercase
if ignore_case:
search_strings = [s.lower() for s in search_strings]
if search_key:
search_key = search_key.lower()
# Look for a specific key and value - entire value must match
if search_key:
key_len = len(search_key)+1
keys = (search_key+":", search_key+" ")
# Read clauses
for clause in read_clauses(files):
found = False
# Read line numbers and lines from clause
for line_no, line in clause:
# Search specific key (key of form "key:" or "key ")
if search_key:
if line[:key_len] in keys:
search_val = line[key_len:].strip()
if ignore_case: search_val.lower()
found = in_search_strings(search_val,search_strings)
if found:
break
# Search entire clause
else:
if ignore_case:
line = line.lower()
for search_string in search_strings:
if line.find(search_string)>=0:
found = True
break
# Search string found, so stop searching this clause.
if found:
break
# Print clause if string found.
if found ^ exclude:
for line_no, line in clause:
# Print line numbers with lines
if print_line_numbers:
print(line_no, line)
# Print lines only (default)
else:
if setvars:
print(get_kvformat(line))
else:
print(line)
print()