Guest User

Untitled

a guest
Aug 4th, 2018
121
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Perl 17.99 KB | None | 0 0
  1. #!C:\Program Files\Perl\bin\wperl.exe
  2. # Created By Bert.Mcguirk@gmail.com
  3. # VERSION 1.2
  4.  
  5. die "This script is intended to run on a windows machine" unless ( $^O eq "MSWin32" );
  6. use File::Path;
  7. use File::Find;
  8. use Tk;
  9. use Tk::LabFrame;
  10. require Tk::ROText;
  11.  
  12.  
  13. our $eventpad ='';  #message board
  14. our @output;
  15. our @errors;
  16.  
  17.  
  18. &make_gui;
  19. MainLoop;
  20.  
  21. ##########################################START GUI FUNCTION###########################################
  22. sub make_gui{
  23.     my $last_line;
  24.     my $mw = MainWindow->new;
  25.     # Mainwindow: size x/y, position x/y
  26.     $mw->geometry("620x575+100+120");
  27.     $mw ->title("svgrep 1.0");
  28.     # Logging window
  29.     $eventpad = $mw->Scrolled(
  30.             # RO = Read Only
  31.             'ROText',  
  32.             # scrollbar on the right
  33.             -scrollbars => 'e',
  34.             -background => 'white',
  35.             # width/height in characters
  36.             -width => 83,
  37.             -height => 10,
  38.     )->place( -x => 8, -y => 415);
  39.     $eventpad->insert('end', sprintf("[" . localtime() . "]" .
  40.         "Event Logging will be shown here\n"));
  41.     my $label1 = $mw->Label(
  42.             -text => "Simple Visual grep",
  43.             -font => "Helvetica -20 ",
  44.     )->place( -x => 210, -y => 05);
  45.     my $label2 = $mw->Label(
  46.             -text => "OR",
  47.             -font => "Helvetica -20 ",
  48.     )->place( -x => 500, -y => 300);
  49.     &required_parameter_frame($mw);
  50.     &add_lines_frame($mw);
  51.     &advanced_options_frame($mw);
  52.     &text_block_frame($mw);
  53. ###################################load saved parameters by default #####################################3#############
  54.     if (-e "search parameters.txt") {
  55.         open (SAVED_SEARCH, "<" . "search parameters.txt");
  56.         my @data = <SAVED_SEARCH>;
  57.        
  58.         # Check for my pipe delimiter on the line to consider it a valid line.
  59.         if ($data[$#data] =~ /\|/){
  60.             $last_line = $data[$#data];
  61.         }else{
  62.             for(my $i = $#data; $i > 0;  $i--) {
  63.                 if ($data[$i] =~ /\|/) {
  64.                     $last_line = $data[$i];
  65.                     $i=0; # correct line found, exit loop.
  66.                 }
  67.             }
  68.         }
  69.         close SAVED_SEARCH;
  70.         my @result  = split(/\|/,$last_line);
  71.          $directory = $result[0];
  72.          $search_string = $result[1];
  73.          $lines_above = $result[2];
  74.          $scan_up_string = $result[3];
  75.          $lines_below = $result[4];
  76.          $scan_down_string = $result[5];
  77.          $chk_button_recursive = $result[6];
  78.          $chk_button_show_file = $result[7];
  79.          $chk_button_show_line_number = $result[8];
  80.          $chk_button_save_search = $result[9];
  81.          $lines_below_to_skip = $result[10];
  82.          $lines_below_to_end_text_block = $result[11];
  83.          $scan_down_string_to_end_text_block = $result[12];
  84.         #notify user:
  85.         $eventpad->insert('end', sprintf("[" . localtime() . "]" .
  86.             "Previous inputs have been loaded\n" ));
  87.     }
  88.     ########################## end handling saved search parameters ############################
  89.     $mw->Button(
  90.                 -text => "run grep",
  91.                 #padx/y is to create space IN the button around the text
  92.                 -padx => 5, -pady => 5,
  93.                 -font => "Helvetica -18 ",
  94.                 -command => sub {
  95.                                 # create output file for the regex function
  96.                                 ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) =localtime(time);
  97.                                 our $output_data_file_name = ("output data " . "$hour$min$sec" . ".txt");
  98.                                
  99.                                 #validate numberic inputs.  0 = bad, 1 = good
  100.                                 $valid = 1;
  101.                                 $valid = &validate_inputs( $lines_above,"numeric")if $lines_above;
  102.                                 $valid = &validate_inputs( $lines_below,"numeric")if $lines_below;
  103.                                 $valid = &validate_inputs( $lines_below_to_skip,"numeric")if $lines_below_to_skip;
  104.                                 $valid = &validate_inputs( $lines_below_to_end_text_block,"numeric")
  105.                                     if $lines_below_to_end_text_block;                                 
  106.                                
  107.                                 # catch bad input combinations.
  108.                                 if ($lines_above && $scan_up_string ){
  109.                                     $valid =0;
  110.                                     $eventpad->insert('end', sprintf("[" . localtime() . "]" .
  111.                                             "\nYou must select either a line amount or scan to string, not both \n" ));
  112.                                 }
  113.                                 if ($lines_below && $scan_down_string ){
  114.                                     $valid =0;
  115.                                     $eventpad->insert('end', sprintf("[" . localtime() . "]" .
  116.                                             "\nYou must select either a line amount or scan to string, not both \n" ));
  117.                                 }
  118.                                 if (($lines_above || $lines_below || $scan_up_string || $scan_down_string) &&
  119.                                     ($lines_below_to_skip || $lines_below_to_end_text_block ||
  120.                                         $scan_down_string_to_end_text_block)){
  121.                                     $valid =0;
  122.                                     $eventpad->insert('end', sprintf("[" . localtime() . "]" .
  123.                                             "\nYou must select either add lines option or text block option, not both \n" ));
  124.                                 }
  125.                                
  126.                                 if($valid == 0) {
  127.                                     $eventpad->insert('end', sprintf("[" . localtime() . "]" .
  128.                                             "grep action aborted\n" ));
  129.                                     return; # exit button function, GUI thread will stay alive.
  130.                                 }                                                  
  131.                                
  132.                                 if ($chk_button_save_search == 1) {
  133.                                         open (SAVED_SEARCH, ">>search parameters.txt") or $newerror = 1;
  134.                                         $eventpad->insert('end', sprintf("[" . localtime() . "]" .
  135.                                             "\nMissing search parameters file\n" )) if $newerror;
  136.                                         print SAVED_SEARCH (
  137.                                             $directory . "|" .
  138.                                             $search_string . "|" .
  139.                                             $lines_above . "|" .
  140.                                             $scan_up_string . "|" .
  141.                                             $lines_below . "|" .
  142.                                             $scan_down_string . "|" .
  143.                                             $chk_button_recursive . "|" .
  144.                                             $chk_button_show_file . "|" .
  145.                                             $chk_button_show_line_number  . "|" .
  146.                                             $chk_button_save_search . "|" .
  147.                                             $lines_below_to_skip . "|" .
  148.                                             $lines_below_to_end_text_block . "|" .
  149.                                             $scan_down_string_to_end_text_block ."|" . "\n"
  150.                                         );
  151.                                         close SAVED_SEARCH;
  152.                                 }
  153.                                 if ($directory && $search_string){
  154.                                     $eventpad->insert('end', sprintf("\n\n\n\n[" . localtime() . "]" .
  155.                                         "grep started for search string:[$search_string]\n" .
  156.                                         "Within directory:\n[$directory]\n"
  157.                                         ));
  158.                                     &regex( $directory,
  159.                                             $search_string,
  160.                                             $lines_above,
  161.                                             $scan_up_string,
  162.                                             $lines_below,
  163.                                             $scan_down_string,
  164.                                             $chk_button_recursive,
  165.                                             $chk_button_show_file,
  166.                                             $chk_button_show_line_number,
  167.                                             $chk_button_save_search,
  168.                                             $lines_below_to_skip,
  169.                                             $lines_below_to_end_text_block,
  170.                                             $scan_down_string_to_end_text_block);
  171.                                            
  172.                                     #clear items for next run
  173.                                     ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) =localtime(time);
  174.                                     $output_data_file_name = ("output data " . "$hour$min$sec" . ".txt");
  175.                                     @output='';
  176.                                     @errors='';
  177.                                 }else {
  178.                                     $eventpad->insert('end', sprintf("[" . localtime() . "]" .
  179.                                         "Please enter a directory\nand search string\n"));
  180.                                 }
  181.                             },
  182.                 )->place( -x => 500, -y => 50);
  183. }
  184. sub required_parameter_frame{
  185.     my $mother = shift;
  186.     #####################
  187.     #   Primary frame   #
  188.     #####################
  189.     my $frame = $mother->LabFrame(
  190.         -label=>"Required",
  191.         -width => 200,
  192.         -height => 105, # Pixel
  193.         -font => "Helvetica -12 ",
  194.     )->place(-x=>7,-y=>35);
  195.     $frame->Label(
  196.         -text => 'Enter a Target Directory',
  197.         -font => "Helvetica -12 ",
  198.     )->place( -x => 7, -y => 10);
  199.     $frame ->Entry(
  200.         -width =>30, # width is in characters, not pixel
  201.         -textvariable => \$directory
  202.     )->place( -x => 7, -y => 30);
  203.     $frame->Label(
  204.         -text => 'Search String',
  205.         -font => "Helvetica -12 ",
  206.     )->place( -x => 7, -y => 50);
  207.     $frame ->Entry(
  208.         -width =>30,    # width is in characters, not pixel
  209.         -textvariable => \$search_string
  210.     )->place( -x => 7, -y => 70);
  211. }
  212. sub add_lines_frame{
  213.     my $mother = shift;
  214.     my $frame = $mother->LabFrame(
  215.         -label=>"Add lines to be returned",
  216.         -width => 200,
  217.         -height => 210,
  218.         -font => "Helvetica -12 ",
  219.     )->place(-x=>7,-y=>165);
  220.     $frame->Label(
  221.         -text => '# of lines above search string',
  222.         -font => "Helvetica -12 ",
  223.     )->place( -x => 7, -y => 10);
  224.     $frame ->Entry(
  225.         -width =>30,    # width is in characters, not pixel
  226.         -textvariable => \$lines_above
  227.     )->place( -x => 7, -y => 30);
  228.     $frame->Label(
  229.         -text => 'OR Scan up to this string',
  230.         -font => "Helvetica -12 ",
  231.     )->place( -x => 7, -y => 50);
  232.     $frame ->Entry(
  233.         -width =>30,    # width is in characters, not pixel
  234.         -textvariable => \$scan_up_string
  235.     )->place( -x => 7, -y => 70);
  236.     $frame->Label(
  237.         -text => '# of lines below search string',
  238.         -font => "Helvetica -12 ",
  239.     )->place( -x => 7, -y => 110);
  240.     $frame ->Entry(
  241.         -width =>30,    # width is in characters, not pixel
  242.         -textvariable => \$lines_below
  243.     )->place( -x => 7, -y => 130);
  244.     $frame->Label(
  245.         -text => 'OR scan down to this string',
  246.         -font => "Helvetica -12 ",
  247.     )->place( -x => 7, -y => 150);
  248.     $frame ->Entry(
  249.         -width =>30,    # width is in characters, not pixel
  250.         -textvariable => \$scan_down_string
  251.     )->place( -x => 7, -y => 170);
  252. }
  253. sub advanced_options_frame{
  254.     my $mother = shift;
  255.     my $frame = $mother->LabFrame(
  256.             -label=>"Advanced Options",
  257.             -width => 200,
  258.             -height => 105, # Pixel
  259.             -font => "Helvetica -12 ",
  260.         )->place(-x=>250,-y=>35);
  261.        
  262.     # check buttons are set to 0 for deselect and 1 for select
  263.     my $chk1 = $frame-> Checkbutton(-text=>"Recursive Directory Search",
  264.     -variable=>\$chk_button_recursive)->place( -x => 7, -y => 7);
  265.     $chk1 -> deselect();
  266.    
  267.     my $chk2 = $frame -> Checkbutton(-text=>"Show File Name in Output",
  268.     -variable=>\$chk_button_show_file)->place( -x => 7, -y => 28);
  269.     $chk2 -> deselect();
  270.    
  271.     my $chk3 = $frame -> Checkbutton(-text=>"Show Line Number in Output",
  272.     -variable=>\$chk_button_show_line_number)->place( -x => 7, -y => 49);
  273.     $chk3 -> deselect();
  274.    
  275.     my $chk4 = $frame -> Checkbutton(-text=>"Save search parameters",
  276.     -variable=>\$chk_button_save_search)->place( -x => 7, -y => 69);
  277.     $chk4 -> select();
  278. }
  279. sub text_block_frame {
  280.     my $mother = shift;
  281.     my $frame = $mother->LabFrame(
  282.         -label=>"Define a text block to be returned (simulate AWK)",
  283.         -width => 350,
  284.         -height => 180,
  285.         -font => "Helvetica -12 ",
  286.     )->place(-x=>250,-y=>175);
  287.     $frame->Label(
  288.         -text => '# of lines to skip below search string to start output',
  289.         -font => "Helvetica -12 ",
  290.     )->place( -x => 60, -y => 30);
  291.     $frame ->Entry(
  292.         -width =>6, # width is in characters, not pixel
  293.         -textvariable=> \$lines_below_to_skip
  294.     )->place( -x => 7, -y => 30);
  295.     $frame->Label(
  296.         -text => 'total # of lines to output',
  297.         -font => "Helvetica -12 ",
  298.     )->place( -x => 150, -y => 80);
  299.     $frame ->Entry(
  300.         -width =>20,    # width is in characters, not pixel
  301.         -textvariable => \$lines_below_to_end_text_block
  302.     )->place( -x => 7, -y => 80);
  303.     $frame->Label(
  304.         -text => 'OR',
  305.         -font => "Helvetica -12 ",
  306.     )->place( -x => 180, -y => 110);
  307.     $frame->Label(
  308.         -text => 'End text block at this string',
  309.         -font => "Helvetica -12 ",
  310.     )->place( -x => 150, -y => 130);
  311.     $frame ->Entry(
  312.         -width =>20,    # width is in characters, not pixel
  313.         -textvariable => \$scan_down_string_to_end_text_block
  314.     )->place( -x => 7, -y => 130);
  315. }
  316. ##########################################END GUI FUNCTIONs###########################################
  317. sub regex {
  318.     # passed variables
  319.     ($directory,
  320.     $search_string,
  321.     $lines_above,
  322.     $scan_up_string,
  323.     $lines_below,
  324.     $scan_down_string,
  325.     $chk_button_recursive,
  326.     $chk_button_show_file,
  327.     $chk_button_show_line_number,
  328.     $chk_button_save_search,
  329.     $lines_below_to_skip,
  330.     $lines_below_to_end_text_block,
  331.     $scan_down_string_to_end_text_block )  = @_;
  332.    
  333.     if  ($chk_button_recursive){
  334.         $max_depth = '99';
  335.     }else{
  336.         $max_depth = '0';
  337.     }
  338.    
  339.     #will traverse all sub directories if allowed by the depth check
  340.     find (\&wanted, $directory);
  341.    
  342.     sub wanted{
  343.         #Directory Depth control
  344.         my $depth = $File::Find::dir =~ tr[/|\\][];  # line_count the slashes, windows or unix style
  345.         return if $depth > $max_depth;
  346.        
  347.         if (-f $_){
  348.             unless (open FILE, $_) {
  349.                 push @errors, "Can't open $File::Find::name : $!";
  350.                 $eventpad->insert('end', sprintf("[" . localtime() . "]" .
  351.                     "Can't open $File::Find::name : $!\n"));
  352.                 return;
  353.             }
  354.             @data = <FILE>; #load whole file into an array
  355.             for ($line_count = 0 ; $line_count < $#data; $line_count++)  {
  356.                 chomp($data[$line_count]); #strip end of lines and extra with space.
  357.                
  358.                 # index function returns -1 if no match
  359.                 if ( index($data[$line_count],$search_string) >= 0 ) {
  360.                     $positive_match = 1;
  361.                    
  362.                     unless( $lines_above  ||  $lines_below  ||  $lines_below_to_skip  ||
  363.                         $lines_below_to_end_text_block  ||  $scan_down_string_to_end_text_block ||
  364.                         $scan_up_string || $scan_down_string){
  365.                        
  366.                         &send_output($out,$chk_button_show_line_number,$chk_button_show_file,
  367.                             $File::Find::name,$line_count,$data[$line_count]);
  368.                     }
  369.                     #start add lines option ->
  370.                     if ($lines_above || $lines_below || $scan_up_string || $scan_down_string){
  371.                        
  372.                         $start_line = $line_count - $lines_above;
  373.                         $stop_line = $lines_below + $line_count;
  374.                
  375.                         if ($scan_up_string){
  376.                             $match='';
  377.                             for ( $i = $line_count; $i >= 0; $i-- ){
  378.                                 if (index($data[$i],$scan_up_string) >= 0 ) {
  379.                                     $start_line = $i;
  380.                                     $i = 0; # exit loop
  381.                                     $match =1;
  382.                                 }
  383.                             }
  384.                             unless ($match){
  385.                                 $eventpad->insert('end', sprintf("[" . localtime() .
  386.                                     "]Could not find scan up string:" .
  387.                                     "[$scan_up_string] in file:\n" .
  388.                                     "[$File::Find::name]\n"));
  389.                                 push @errors, ( "Could not find scan up string: [$scan_up_string]" .
  390.                                     "in file: $File::Find::name");
  391.                                 &make_error_log;
  392.                                 $match='';
  393.                                 $positive_match='';
  394.                                 return;
  395.                             }
  396.                         }
  397.                         if ($scan_down_string){
  398.                             $match='';
  399.                             for ($i=$line_count; $i<$#data ; $i++){
  400.                                 if (index($data[$i],$scan_down_string)>=0) {
  401.                                     $stop_line=$i;
  402.                                     $i=$#data; # exit loop
  403.                                     $match=1;
  404.                                 }
  405.                             }
  406.                             unless ($match){
  407.                                 $eventpad->insert('end', sprintf("[" . localtime() .
  408.                                     "]Could not find scan down string:" .
  409.                                     "[$scan_down_string] in file:\n" .
  410.                                     "[$File::Find::name]\n"));
  411.                                 push @errors, ( "Could not find scan up string: [$scan_down_string]" .
  412.                                     "in file: $File::Find::name");
  413.                                 &make_error_log;
  414.                                 $match='';
  415.                                 $positive_match ='';
  416.                                 return;
  417.                             }
  418.                         }
  419.                         #send data from start line to matched line
  420.                         if ($lines_above || $scan_up_string){
  421.                             for ($i=$start_line; $i<$line_count; $i++) {
  422.                                 &send_output($out,$chk_button_show_line_number,
  423.                                     $chk_button_show_file,$File::Find::name,$i,$data[$i]);
  424.                             }
  425.                         }
  426.                         #send matched line out
  427.                         &send_output($out, $chk_button_show_line_number,$chk_button_show_file,
  428.                             $File::Find::name, $line_count, $data[$line_count]);
  429.                         #send lines after matched line down to the new stopping point.
  430.                         if ($lines_below || $scan_down_string){
  431.                             #start right after matched line
  432.                             for ($i=($line_count+1); $i<=$stop_line;$i++) {
  433.                                     &send_output($out, $chk_button_show_line_number, $chk_button_show_file,
  434.                                         $File::Find::name, $i, $data[$i]);
  435.                                 }
  436.                             }
  437.                     }
  438.                     #end add lines option <-
  439.                    
  440.                     #start textblock options->
  441.                     if ($lines_below_to_skip || $lines_below_to_end_text_block ||
  442.                         $scan_down_string_to_end_text_block ){
  443.                        
  444.                         #start at matched line if lines below to skip wasn't
  445.                         $lines_below_to_skip = 0 unless ($lines_below_to_skip);
  446.                         $start_line = ($line_count+$lines_below_to_skip);
  447.                                        
  448.                         if  ($scan_down_string_to_end_text_block){
  449.                             $match='';
  450.                             for ( $i = $start_line; $i < $#data ;$i++){
  451.                                 if (index("$data[$i]",$scan_down_string_to_end_text_block) >= 0) {
  452.                                     $stop_line = $i;
  453.                                     $i = $#data; # exit loop
  454.                                     $match = 1;
  455.                                 }
  456.                             }
  457.                             unless ($match){
  458.                                 $eventpad->insert('end', sprintf("[" . localtime() . "]Could not find scan down string:" .
  459.                                     "[$scan_down_string] in file:\n" .
  460.                                     "[$File::Find::name]\n"));
  461.                                 push @errors, ( "Could not find scan up string: [$scan_down_string]" .
  462.                                     "in file: $File::Find::name");
  463.                                 &make_error_log;
  464.                                 $match ='';
  465.                                 $positive_match ='';
  466.                                 return;
  467.                             }
  468.                         } else {
  469.                             $stop_line = ($lines_below_to_end_text_block + $start_line);
  470.                         }
  471.                         for ( my $i = $start_line; $i <= $stop_line; $i++ ) {
  472.                             &send_output($out, $chk_button_show_line_number,$chk_button_show_file,
  473.                                 $File::Find::name, $i, $data[$i]);
  474.                         }
  475.                     }
  476.                     # end text block options <-
  477.                     close FILE;
  478.                     return;
  479.                 }
  480.             }
  481.         }
  482.     close FILE;
  483.     }
  484.    
  485.     # create output file ONLY if there is a match
  486.     if ($positive_match){
  487.         open(OUT, ">$output_data_file_name");
  488.         foreach (@output){print OUT ($_ . "\n");}
  489.         close(OUT);
  490.         $eventpad->insert('end', sprintf("[" . localtime() . "]" .
  491.             "Results have been found, please check output file.\n"));
  492.         $eventpad->insert('end', sprintf("[" . localtime() . "]" .
  493.             "Created output file: $output_data_file_name \n"));
  494.     }else{
  495.         $eventpad->insert('end', sprintf("[" . localtime() . "]" .
  496.             "No results found :( \n"));
  497.         push @errors, "[" . localtime() . "]" .
  498.             "No results found in directory: [$directory]";
  499.     }
  500.     &make_error_log;
  501. }
  502.  
  503. sub make_error_log{
  504.     if($errors[0]){
  505.         open(ERROR_LOG, ">error log.txt");
  506.         foreach (@errors){print ERROR_LOG ($_ ."\n");}
  507.         close(ERROR_LOG);
  508.        
  509.         $eventpad->insert('end', sprintf("[" . localtime() . "]" .
  510.             "$#errors Erorrs have been sent to the error log file.\n"));
  511.     }
  512. }
  513. sub send_output{
  514.     my ($out,$show_line,$show_file_name, $file_name,$line_count, $data) = @_;
  515.     chomp($data); #strp end of line's to avoid double spacing.
  516.     if ($show_line && $show_file_name){
  517.         push @output, ("$file_name" . "," . "$line_count" . "," . "$data");
  518.     }elsif($show_file_name){
  519.         push @output, ("$file_name" . "," . "$data");
  520.     }elsif($show_line){
  521.         push @output, ("$line_count" . "," . "$data");
  522.     }else{
  523.         push @output,("$data");
  524.     }
  525. }
  526. sub validate_inputs{
  527.     ($user_response, $type) = @_;
  528.     if ($user_response =~ /^[+-]?\d+$/){
  529.         return 1 if $type eq "number";  # this isn't needed but made the code clearer to me when debugging.  
  530.     }else{
  531.         $eventpad->insert('end', sprintf("[" . localtime() . "]" .
  532.         "Invalid entry: [$user_response]\n"));     
  533.         return 0;
  534.     }
  535.  }
Add Comment
Please, Sign In to add comment