#!/usr/bin/gawk -f
#
# Usage:
# on the commandline
#
# Put grawk into your /usr/local/bin path, and call without ./
# grawk [start keyword search]  [start position Integar] [end of line character/word] [end position integar (or $ for end of line)] ["inc"/"exc" to include 1 or exclude 1 character] file
# 
# ./grawk CRON 1 ")" 2 /var/log/syslog 
# OUTPUT: This will search for the first instance CRON as a starting string up to the second instance of ")" from syslog
# 
# ./grawk CRON 1 $ /var/log/syslog 
# OUTPUT: Search for first instance of CRON to end of the line from syslog
#
# ./grawk root 1 "/" 1 exc /etc/passwd
# OUTPUT:
# root:x:0:0:root:
# root:x:524288:524288::
#
# ./grawk root 1 "/" 2 exc /etc/passwd
# root:x:0:0:root:/root:
# root:x:524288:524288::/nonexistent:
#
# ./grawk dns 1 "," 1 exc /etc/passwd
# OUTPUT:
# dnsmasq:x:112:65534:dnsmasq
# dnsmasq:x:132:141:Libvirt Dnsmasq
# 
# cat /etc/passwd | ./grawk root $
# OUTPUT:
# root:x:0:0:root:/root:/bin/bash
# root:/usr/sbin/nologin
# root:x:524288:524288::/nonexistent:/usr/bin/false

BEGIN{
	# start string search
	start = ARGV[1]
	delete ARGV[1]
	
	# does start have a number value option (flag) between 1-9, if so add a num1 counter to other ARGVs
	if ( ARGV[2] ~ "[1-9]{1}" ) {
		startappear = ARGV[2]
		num1 += 1
		delete ARGV[2]
		}
	
	# Last string pattern to extract up to, from the start string
	last = ARGV[2 + num1]
	
	# length of the last string to be used at the end to calculate string size
	len=length(last)
	delete ARGV[2 + num1]
	
	# instance number for end character/word 
	if (ARGV[3 + num1] ~ "[$1-9]{1}" ) {
		lastappear = ARGV[3 + num1]
		delete ARGV[3 + num1]
		num1 += 1
		}

	# Including an exc argument at the end of the command line will exclude the last character, unless last == "$"
	# If last == "$" the line printed will begin at start, finish at the end of the line.
	# If the last charactaer is a /, and $ is not included with exc, then a search of /home/user/ will turn into /home/user 
	# inc is the opposite of exc
	if (ARGV[3 + num1] == "exc") {
		len -= 1
		delete ARGV[3 + num1]
		}
	if (ARGV[3 + num1] == "inc") {
		len += 1
		delete ARGV[3 + num1]
		}
}
{
	# What this section does, is look for the start flag value, i.e. grawk root 2 $ /etc/passwd will use the second instance root is found in a line,
	# and with the $ flag, it'll print to the end of line.
	# grawk root 2 "/" 1 will look for the second instance of root in a line, and print up to the first "/"
	# grawk root 2 "/" 1  exc , will look for the second instance of root in a line, and print up to the first "/", excluding the last character "/"
	# There is another hacky thing you can do if you just want the whole line, and place a period before the start search.
	# Note: == 1 is not included because the first instance is the default, but the 1 flag is still required

	for (m=2 ; m<=startappear ; m++) {
		$0 = gensub(start,"",1)
		}

	if ( start == "[" ) {
		start="\\["
		}
	if ( last == "]" ) {
		last="\\]"
		}
	
	$0 ~ start && $0 ~ last && b[lines++]=$0 

	if ( start == "\\[" ) {
		start="["
		}
	if ( last == "\\]" ) {
		last="]"
		}
	# delim with inrefrequent characters to help separate and reintroduce into final output.
	if (! /"¬"/ ) {
		delim="¬"
	} else if (! /"¶"/ ) {
		delim="¶"
	} else if (! /"¥"/ ) {
		delim="¥"
	}
}

# This below uses the data above to index and format the desired (hopefully) string output.
END{
	for (i in b) {
		if ( last == "$" || lastappear == "$") {
			n=index(b[i],start)
			z=substr(b[i],n)
			if (z != "") {
				print "\033[33m"z"\033[0m"    		
			}    		
		} else {
			n=index(b[i],start)
			t=substr(b[i],n)
			# This section needs to occur once the start of the string has been established, i.e. indexed and substr.
			if ( lastappear == 1 ) {f=index(t,start) ; c=index(t,last); z=substr(t,1,c+len-1) ; if (z != "") print "\033[33m"z"\033[0m" ; continue}
			g = gensub(last,delim,1,t)
			for (m=3 ; m<=lastappear ; m++) {
				g = gensub(last,delim,1,g)
				}
			c=index(g,last)
			z=substr(g,1,c+len-1)
			gsub(delim,last,z)
			if (z != "") {
				print "\033[33m"z"\033[0m"    		
			}
		}
	}
}