#!/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" } } } }