Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #!C:\Program Files\Perl\bin\wperl.exe
- # Created By Bert.Mcguirk@gmail.com
- # VERSION 1.2
- die "This script is intended to run on a windows machine" unless ( $^O eq "MSWin32" );
- use File::Path;
- use File::Find;
- use Tk;
- use Tk::LabFrame;
- require Tk::ROText;
- our $eventpad =''; #message board
- our @output;
- our @errors;
- &make_gui;
- MainLoop;
- ##########################################START GUI FUNCTION###########################################
- sub make_gui{
- my $last_line;
- my $mw = MainWindow->new;
- # Mainwindow: size x/y, position x/y
- $mw->geometry("620x575+100+120");
- $mw ->title("svgrep 1.0");
- # Logging window
- $eventpad = $mw->Scrolled(
- # RO = Read Only
- 'ROText',
- # scrollbar on the right
- -scrollbars => 'e',
- -background => 'white',
- # width/height in characters
- -width => 83,
- -height => 10,
- )->place( -x => 8, -y => 415);
- $eventpad->insert('end', sprintf("[" . localtime() . "]" .
- "Event Logging will be shown here\n"));
- my $label1 = $mw->Label(
- -text => "Simple Visual grep",
- -font => "Helvetica -20 ",
- )->place( -x => 210, -y => 05);
- my $label2 = $mw->Label(
- -text => "OR",
- -font => "Helvetica -20 ",
- )->place( -x => 500, -y => 300);
- &required_parameter_frame($mw);
- &add_lines_frame($mw);
- &advanced_options_frame($mw);
- &text_block_frame($mw);
- ###################################load saved parameters by default #####################################3#############
- if (-e "search parameters.txt") {
- open (SAVED_SEARCH, "<" . "search parameters.txt");
- my @data = <SAVED_SEARCH>;
- # Check for my pipe delimiter on the line to consider it a valid line.
- if ($data[$#data] =~ /\|/){
- $last_line = $data[$#data];
- }else{
- for(my $i = $#data; $i > 0; $i--) {
- if ($data[$i] =~ /\|/) {
- $last_line = $data[$i];
- $i=0; # correct line found, exit loop.
- }
- }
- }
- close SAVED_SEARCH;
- my @result = split(/\|/,$last_line);
- $directory = $result[0];
- $search_string = $result[1];
- $lines_above = $result[2];
- $scan_up_string = $result[3];
- $lines_below = $result[4];
- $scan_down_string = $result[5];
- $chk_button_recursive = $result[6];
- $chk_button_show_file = $result[7];
- $chk_button_show_line_number = $result[8];
- $chk_button_save_search = $result[9];
- $lines_below_to_skip = $result[10];
- $lines_below_to_end_text_block = $result[11];
- $scan_down_string_to_end_text_block = $result[12];
- #notify user:
- $eventpad->insert('end', sprintf("[" . localtime() . "]" .
- "Previous inputs have been loaded\n" ));
- }
- ########################## end handling saved search parameters ############################
- $mw->Button(
- -text => "run grep",
- #padx/y is to create space IN the button around the text
- -padx => 5, -pady => 5,
- -font => "Helvetica -18 ",
- -command => sub {
- # create output file for the regex function
- ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) =localtime(time);
- our $output_data_file_name = ("output data " . "$hour$min$sec" . ".txt");
- #validate numberic inputs. 0 = bad, 1 = good
- $valid = 1;
- $valid = &validate_inputs( $lines_above,"numeric")if $lines_above;
- $valid = &validate_inputs( $lines_below,"numeric")if $lines_below;
- $valid = &validate_inputs( $lines_below_to_skip,"numeric")if $lines_below_to_skip;
- $valid = &validate_inputs( $lines_below_to_end_text_block,"numeric")
- if $lines_below_to_end_text_block;
- # catch bad input combinations.
- if ($lines_above && $scan_up_string ){
- $valid =0;
- $eventpad->insert('end', sprintf("[" . localtime() . "]" .
- "\nYou must select either a line amount or scan to string, not both \n" ));
- }
- if ($lines_below && $scan_down_string ){
- $valid =0;
- $eventpad->insert('end', sprintf("[" . localtime() . "]" .
- "\nYou must select either a line amount or scan to string, not both \n" ));
- }
- if (($lines_above || $lines_below || $scan_up_string || $scan_down_string) &&
- ($lines_below_to_skip || $lines_below_to_end_text_block ||
- $scan_down_string_to_end_text_block)){
- $valid =0;
- $eventpad->insert('end', sprintf("[" . localtime() . "]" .
- "\nYou must select either add lines option or text block option, not both \n" ));
- }
- if($valid == 0) {
- $eventpad->insert('end', sprintf("[" . localtime() . "]" .
- "grep action aborted\n" ));
- return; # exit button function, GUI thread will stay alive.
- }
- if ($chk_button_save_search == 1) {
- open (SAVED_SEARCH, ">>search parameters.txt") or $newerror = 1;
- $eventpad->insert('end', sprintf("[" . localtime() . "]" .
- "\nMissing search parameters file\n" )) if $newerror;
- print SAVED_SEARCH (
- $directory . "|" .
- $search_string . "|" .
- $lines_above . "|" .
- $scan_up_string . "|" .
- $lines_below . "|" .
- $scan_down_string . "|" .
- $chk_button_recursive . "|" .
- $chk_button_show_file . "|" .
- $chk_button_show_line_number . "|" .
- $chk_button_save_search . "|" .
- $lines_below_to_skip . "|" .
- $lines_below_to_end_text_block . "|" .
- $scan_down_string_to_end_text_block ."|" . "\n"
- );
- close SAVED_SEARCH;
- }
- if ($directory && $search_string){
- $eventpad->insert('end', sprintf("\n\n\n\n[" . localtime() . "]" .
- "grep started for search string:[$search_string]\n" .
- "Within directory:\n[$directory]\n"
- ));
- ®ex( $directory,
- $search_string,
- $lines_above,
- $scan_up_string,
- $lines_below,
- $scan_down_string,
- $chk_button_recursive,
- $chk_button_show_file,
- $chk_button_show_line_number,
- $chk_button_save_search,
- $lines_below_to_skip,
- $lines_below_to_end_text_block,
- $scan_down_string_to_end_text_block);
- #clear items for next run
- ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) =localtime(time);
- $output_data_file_name = ("output data " . "$hour$min$sec" . ".txt");
- @output='';
- @errors='';
- }else {
- $eventpad->insert('end', sprintf("[" . localtime() . "]" .
- "Please enter a directory\nand search string\n"));
- }
- },
- )->place( -x => 500, -y => 50);
- }
- sub required_parameter_frame{
- my $mother = shift;
- #####################
- # Primary frame #
- #####################
- my $frame = $mother->LabFrame(
- -label=>"Required",
- -width => 200,
- -height => 105, # Pixel
- -font => "Helvetica -12 ",
- )->place(-x=>7,-y=>35);
- $frame->Label(
- -text => 'Enter a Target Directory',
- -font => "Helvetica -12 ",
- )->place( -x => 7, -y => 10);
- $frame ->Entry(
- -width =>30, # width is in characters, not pixel
- -textvariable => \$directory
- )->place( -x => 7, -y => 30);
- $frame->Label(
- -text => 'Search String',
- -font => "Helvetica -12 ",
- )->place( -x => 7, -y => 50);
- $frame ->Entry(
- -width =>30, # width is in characters, not pixel
- -textvariable => \$search_string
- )->place( -x => 7, -y => 70);
- }
- sub add_lines_frame{
- my $mother = shift;
- my $frame = $mother->LabFrame(
- -label=>"Add lines to be returned",
- -width => 200,
- -height => 210,
- -font => "Helvetica -12 ",
- )->place(-x=>7,-y=>165);
- $frame->Label(
- -text => '# of lines above search string',
- -font => "Helvetica -12 ",
- )->place( -x => 7, -y => 10);
- $frame ->Entry(
- -width =>30, # width is in characters, not pixel
- -textvariable => \$lines_above
- )->place( -x => 7, -y => 30);
- $frame->Label(
- -text => 'OR Scan up to this string',
- -font => "Helvetica -12 ",
- )->place( -x => 7, -y => 50);
- $frame ->Entry(
- -width =>30, # width is in characters, not pixel
- -textvariable => \$scan_up_string
- )->place( -x => 7, -y => 70);
- $frame->Label(
- -text => '# of lines below search string',
- -font => "Helvetica -12 ",
- )->place( -x => 7, -y => 110);
- $frame ->Entry(
- -width =>30, # width is in characters, not pixel
- -textvariable => \$lines_below
- )->place( -x => 7, -y => 130);
- $frame->Label(
- -text => 'OR scan down to this string',
- -font => "Helvetica -12 ",
- )->place( -x => 7, -y => 150);
- $frame ->Entry(
- -width =>30, # width is in characters, not pixel
- -textvariable => \$scan_down_string
- )->place( -x => 7, -y => 170);
- }
- sub advanced_options_frame{
- my $mother = shift;
- my $frame = $mother->LabFrame(
- -label=>"Advanced Options",
- -width => 200,
- -height => 105, # Pixel
- -font => "Helvetica -12 ",
- )->place(-x=>250,-y=>35);
- # check buttons are set to 0 for deselect and 1 for select
- my $chk1 = $frame-> Checkbutton(-text=>"Recursive Directory Search",
- -variable=>\$chk_button_recursive)->place( -x => 7, -y => 7);
- $chk1 -> deselect();
- my $chk2 = $frame -> Checkbutton(-text=>"Show File Name in Output",
- -variable=>\$chk_button_show_file)->place( -x => 7, -y => 28);
- $chk2 -> deselect();
- my $chk3 = $frame -> Checkbutton(-text=>"Show Line Number in Output",
- -variable=>\$chk_button_show_line_number)->place( -x => 7, -y => 49);
- $chk3 -> deselect();
- my $chk4 = $frame -> Checkbutton(-text=>"Save search parameters",
- -variable=>\$chk_button_save_search)->place( -x => 7, -y => 69);
- $chk4 -> select();
- }
- sub text_block_frame {
- my $mother = shift;
- my $frame = $mother->LabFrame(
- -label=>"Define a text block to be returned (simulate AWK)",
- -width => 350,
- -height => 180,
- -font => "Helvetica -12 ",
- )->place(-x=>250,-y=>175);
- $frame->Label(
- -text => '# of lines to skip below search string to start output',
- -font => "Helvetica -12 ",
- )->place( -x => 60, -y => 30);
- $frame ->Entry(
- -width =>6, # width is in characters, not pixel
- -textvariable=> \$lines_below_to_skip
- )->place( -x => 7, -y => 30);
- $frame->Label(
- -text => 'total # of lines to output',
- -font => "Helvetica -12 ",
- )->place( -x => 150, -y => 80);
- $frame ->Entry(
- -width =>20, # width is in characters, not pixel
- -textvariable => \$lines_below_to_end_text_block
- )->place( -x => 7, -y => 80);
- $frame->Label(
- -text => 'OR',
- -font => "Helvetica -12 ",
- )->place( -x => 180, -y => 110);
- $frame->Label(
- -text => 'End text block at this string',
- -font => "Helvetica -12 ",
- )->place( -x => 150, -y => 130);
- $frame ->Entry(
- -width =>20, # width is in characters, not pixel
- -textvariable => \$scan_down_string_to_end_text_block
- )->place( -x => 7, -y => 130);
- }
- ##########################################END GUI FUNCTIONs###########################################
- sub regex {
- # passed variables
- ($directory,
- $search_string,
- $lines_above,
- $scan_up_string,
- $lines_below,
- $scan_down_string,
- $chk_button_recursive,
- $chk_button_show_file,
- $chk_button_show_line_number,
- $chk_button_save_search,
- $lines_below_to_skip,
- $lines_below_to_end_text_block,
- $scan_down_string_to_end_text_block ) = @_;
- if ($chk_button_recursive){
- $max_depth = '99';
- }else{
- $max_depth = '0';
- }
- #will traverse all sub directories if allowed by the depth check
- find (\&wanted, $directory);
- sub wanted{
- #Directory Depth control
- my $depth = $File::Find::dir =~ tr[/|\\][]; # line_count the slashes, windows or unix style
- return if $depth > $max_depth;
- if (-f $_){
- unless (open FILE, $_) {
- push @errors, "Can't open $File::Find::name : $!";
- $eventpad->insert('end', sprintf("[" . localtime() . "]" .
- "Can't open $File::Find::name : $!\n"));
- return;
- }
- @data = <FILE>; #load whole file into an array
- for ($line_count = 0 ; $line_count < $#data; $line_count++) {
- chomp($data[$line_count]); #strip end of lines and extra with space.
- # index function returns -1 if no match
- if ( index($data[$line_count],$search_string) >= 0 ) {
- $positive_match = 1;
- unless( $lines_above || $lines_below || $lines_below_to_skip ||
- $lines_below_to_end_text_block || $scan_down_string_to_end_text_block ||
- $scan_up_string || $scan_down_string){
- &send_output($out,$chk_button_show_line_number,$chk_button_show_file,
- $File::Find::name,$line_count,$data[$line_count]);
- }
- #start add lines option ->
- if ($lines_above || $lines_below || $scan_up_string || $scan_down_string){
- $start_line = $line_count - $lines_above;
- $stop_line = $lines_below + $line_count;
- if ($scan_up_string){
- $match='';
- for ( $i = $line_count; $i >= 0; $i-- ){
- if (index($data[$i],$scan_up_string) >= 0 ) {
- $start_line = $i;
- $i = 0; # exit loop
- $match =1;
- }
- }
- unless ($match){
- $eventpad->insert('end', sprintf("[" . localtime() .
- "]Could not find scan up string:" .
- "[$scan_up_string] in file:\n" .
- "[$File::Find::name]\n"));
- push @errors, ( "Could not find scan up string: [$scan_up_string]" .
- "in file: $File::Find::name");
- &make_error_log;
- $match='';
- $positive_match='';
- return;
- }
- }
- if ($scan_down_string){
- $match='';
- for ($i=$line_count; $i<$#data ; $i++){
- if (index($data[$i],$scan_down_string)>=0) {
- $stop_line=$i;
- $i=$#data; # exit loop
- $match=1;
- }
- }
- unless ($match){
- $eventpad->insert('end', sprintf("[" . localtime() .
- "]Could not find scan down string:" .
- "[$scan_down_string] in file:\n" .
- "[$File::Find::name]\n"));
- push @errors, ( "Could not find scan up string: [$scan_down_string]" .
- "in file: $File::Find::name");
- &make_error_log;
- $match='';
- $positive_match ='';
- return;
- }
- }
- #send data from start line to matched line
- if ($lines_above || $scan_up_string){
- for ($i=$start_line; $i<$line_count; $i++) {
- &send_output($out,$chk_button_show_line_number,
- $chk_button_show_file,$File::Find::name,$i,$data[$i]);
- }
- }
- #send matched line out
- &send_output($out, $chk_button_show_line_number,$chk_button_show_file,
- $File::Find::name, $line_count, $data[$line_count]);
- #send lines after matched line down to the new stopping point.
- if ($lines_below || $scan_down_string){
- #start right after matched line
- for ($i=($line_count+1); $i<=$stop_line;$i++) {
- &send_output($out, $chk_button_show_line_number, $chk_button_show_file,
- $File::Find::name, $i, $data[$i]);
- }
- }
- }
- #end add lines option <-
- #start textblock options->
- if ($lines_below_to_skip || $lines_below_to_end_text_block ||
- $scan_down_string_to_end_text_block ){
- #start at matched line if lines below to skip wasn't
- $lines_below_to_skip = 0 unless ($lines_below_to_skip);
- $start_line = ($line_count+$lines_below_to_skip);
- if ($scan_down_string_to_end_text_block){
- $match='';
- for ( $i = $start_line; $i < $#data ;$i++){
- if (index("$data[$i]",$scan_down_string_to_end_text_block) >= 0) {
- $stop_line = $i;
- $i = $#data; # exit loop
- $match = 1;
- }
- }
- unless ($match){
- $eventpad->insert('end', sprintf("[" . localtime() . "]Could not find scan down string:" .
- "[$scan_down_string] in file:\n" .
- "[$File::Find::name]\n"));
- push @errors, ( "Could not find scan up string: [$scan_down_string]" .
- "in file: $File::Find::name");
- &make_error_log;
- $match ='';
- $positive_match ='';
- return;
- }
- } else {
- $stop_line = ($lines_below_to_end_text_block + $start_line);
- }
- for ( my $i = $start_line; $i <= $stop_line; $i++ ) {
- &send_output($out, $chk_button_show_line_number,$chk_button_show_file,
- $File::Find::name, $i, $data[$i]);
- }
- }
- # end text block options <-
- close FILE;
- return;
- }
- }
- }
- close FILE;
- }
- # create output file ONLY if there is a match
- if ($positive_match){
- open(OUT, ">$output_data_file_name");
- foreach (@output){print OUT ($_ . "\n");}
- close(OUT);
- $eventpad->insert('end', sprintf("[" . localtime() . "]" .
- "Results have been found, please check output file.\n"));
- $eventpad->insert('end', sprintf("[" . localtime() . "]" .
- "Created output file: $output_data_file_name \n"));
- }else{
- $eventpad->insert('end', sprintf("[" . localtime() . "]" .
- "No results found :( \n"));
- push @errors, "[" . localtime() . "]" .
- "No results found in directory: [$directory]";
- }
- &make_error_log;
- }
- sub make_error_log{
- if($errors[0]){
- open(ERROR_LOG, ">error log.txt");
- foreach (@errors){print ERROR_LOG ($_ ."\n");}
- close(ERROR_LOG);
- $eventpad->insert('end', sprintf("[" . localtime() . "]" .
- "$#errors Erorrs have been sent to the error log file.\n"));
- }
- }
- sub send_output{
- my ($out,$show_line,$show_file_name, $file_name,$line_count, $data) = @_;
- chomp($data); #strp end of line's to avoid double spacing.
- if ($show_line && $show_file_name){
- push @output, ("$file_name" . "," . "$line_count" . "," . "$data");
- }elsif($show_file_name){
- push @output, ("$file_name" . "," . "$data");
- }elsif($show_line){
- push @output, ("$line_count" . "," . "$data");
- }else{
- push @output,("$data");
- }
- }
- sub validate_inputs{
- ($user_response, $type) = @_;
- if ($user_response =~ /^[+-]?\d+$/){
- return 1 if $type eq "number"; # this isn't needed but made the code clearer to me when debugging.
- }else{
- $eventpad->insert('end', sprintf("[" . localtime() . "]" .
- "Invalid entry: [$user_response]\n"));
- return 0;
- }
- }
Add Comment
Please, Sign In to add comment