in reply to Break out of program to get correct logic (total count)

You're making this a lot harder than it needs to be.

#!/usr/bin/perl use 5.010; use strict; use File::Slurp qw(edit_file_lines); use Path::Class qw(file dir); use constant SKIP => 'SKIP'; use constant SIMULATION => 1; sub process_file { my ($file, %param) = @_; # skip files that need skipping if ($param{skip}->($file) eq SKIP) { say { $param{log} } "Skipping $file"; return 0; } if ($file->is_dir) { my $modified = 0; say { $param{log} } "Recursing into directory $file"; foreach ($file->children) { $modified += process_file($_, %param); } say { $param{log} } "Finished with directory $file - modified +$modified files inside"; return $modified; } say { $param{log} } "Processing file $file"; my $i = 0; my $modified = 0; edit_file_lines { $i++; foreach my $change (@{ $param{changes} }) { my ($match, $replace) = @$change; if (/$match/) { say { $param{log} } "Line $i matched $match - replacin +g with $replace"; $modified = 1; s/$match/$replace/g unless SIMULATION; } } } $file; say { $param{log} } "Done with file $file"; return $modified; } process_file( # starting point for crawl dir('somedir'), # list of changes to make changes => [ [ qr{ChangeThis}i => 'ToThis' ], [ qr{ChangeThat}i => 'ToThat' ], ], # sub which returns SKIP if a file (or directory) should be skippe +d skip => sub { my $file = shift; if ($file->is_dir and [$file->dir_list]->[-1] !~ /^[a-zA-Z0-9] +/) { return SKIP; } return; }, log => file('changling.log')->openw, );
perl -E'sub Monkey::do{say$_,for@_,do{($monkey=[caller(0)]->[3])=~s{::}{ }and$monkey}}"Monkey say"->Monkey::do'

Replies are listed 'Best First'.
Re^2: Break out of program to get correct logic (total count)
by begood321 (Novice) on May 02, 2012 at 13:59 UTC
    #!\Interwoven\TeamSite\iw-perl\bin\perl -w use strict; use warnings; use diagnostics; # # Purpose: Crawl directories recursively # # Description: This script counts all files within directories and ren +ame appropriate files respectively. # # Author: # use Cwd; # module for finding the current working directory use File::Find; # a core module (no installation needed) # # The location of the PERL executable my $iwperl = "c:\\perl\\bin\\perl -pi.bak -e"; # my $iwperl = "E:\\Interwoven\\TeamSite\\iw-perl\\bin\\iwperl -pi.bak + -e"; my @root= ( ## Workareas ### "Y:\\default\\main\\test.com\\WORKAREA\\www\\templatedata", ); #an array of starting directories my $final_total = 0; # final sum of total files my $dummy = ""; # <enter> to start program # run process my $run = ""; # simulation mode yes (files not modified) or no (files modified) my $sim = ""; # get hostname my $hostname_cmd = "hostname"; `$hostname_cmd`; my $hostname = `$hostname_cmd`; chomp $hostname; # remove carriage return from hostname cmd # Verify correct server # if ($hostname eq "AUTO-CMS") { # call starting sub to begin process on correct serer &press_enter; } else { # Process terminated, incorrect server print "\nReplace production hard code references on global test se +rver process not executed, incorrect server \"$hostname\". Should onl +y run process on global test server \"AUTO-CMS\".\n"; } my $date = localtime; $date =~ s/\b(\d)\b/0$1/g; #pad single digits with zero #this seemed to be a requirement for some #reason my %options = (preprocess =>\&new_dir, wanted=>\&wanted); ## just to make sure the file is emptied before we start my $output_file = qq|C:\\tmp\\prod_ref_results.txt|; open(MYFILE, ">$output_file") || die "opening $output_file: $!"; # ov +erwrite # program started if ($run =~ m/y|Y|yes|YES/) { print MYFILE "Replace production hard code references on test serv +er process started $date\n"; print MYFILE "---------------------------------------------------- +-------------------------------------------------\n"; print "\nReplace prod hard code references on GT process started $ +date\n"; print "----------------------------------------------------------- +---------\n"; foreach(@root) { print "Scanning directory: $_\n"; print MYFILE "Scanning directory: $_\n"; &ScanDirectory($_); } find ( \%options, @root); END: print "FINAL TOTAL FILES MODIFIED: $final_total\n"; # return total + files per directory print MYFILE "FINAL TOTAL FILES MODIFIED: $final_total\n"; # retur +n total files per directory } close MYFILE; #################################################### # put up a message and wait for user to press ENTER #################################################### sub press_enter { print "\nThis process replaces prod hard code references on test. +When run in simulation mode files are not modified, in non-simulation + mode files are modified. A report is created on screen and a more de +tailed report in output file \"C:\\tmp\\prod_ref_results\.txt\"\. To +stop program execution press ctrl c.\n\n"; print "Press Enter to Continue . . .\n"; $dummy = <STDIN>; get_yes_no(); } # End of sub press_enter { ##################################################################### # get user response to 1st question (Run process in simulation mode) ##################################################################### sub get_yes_no { print "Run process in simulation mode, files will NOT be modified\ +?\n"; print "yes/no (y/n)\n"; chomp ( my $res = <STDIN>); if ($res =~ m/n|N|no|NO/) { get_yes_no2(); } elsif ($res =~ m/y|Y|yes|YES/) { print "Process running in simulation mode, files will NOT be m +odified . . .\n"; $sim = "yes"; $run = "yes"; return $sim; return $run; } else { print "Inappropriate answer, process terminated.\n"; exit 0; } } # End of sub get_yes_no { ###################################################################### +### # get user response to 2nd question (Run process in non simulation mod +e) ###################################################################### +### sub get_yes_no2 { print "Run process in non simulation mode, FILES WILL BE MODIFIED\ +?\n"; print "yes/no (y/n)\n"; chomp ( my $res = <STDIN>); if ($res =~ m/n|N|no|NO/) { print "Process running in simulation mode, files will NOT be m +odified . . .\n"; $sim = "yes"; $run = "yes"; return $sim; return $run; } elsif ($res =~ m/y|Y|yes|YES/) { print "Process running in non simulation mode, FILES WILL BE M +ODIFIED . . .\n"; $sim = "no"; $run = "yes"; return $sim; return $run; } else { print "Inappropriate answer, process terminated.\n"; exit 0; } } # End of sub get_yes_no2 { sub ScanDirectory { my ($path) = shift; my($startdir) = &cwd; # keep track of where we began chdir($path) or die "Unable to enter dir $path:$!\n"; opendir(DIR, ".") or die "Unable to open $path:$!\n"; my @names = readdir(DIR); closedir(DIR); } sub new_dir { my @files = @_; # the readdir() output # contains both (files and directories) my $num_files = grep{-f}@files; #-f are simple files my $file_count = 0; # add files my $total_count = 0; # total files # sort files @files = sort(@files); foreach my $name (@files) { if (-d $name) { next if($name !~ m|(^[a-zA-Z0-9])|); next; } if (-e $name) { # skipped next if ($name eq "."); next if ($name eq ".."); # $count++; open(WEBFILE, "$name") || die "opening $name: $!"; # +read my @file = <WEBFILE>; close(WEBFILE); my @change_file = qw(); my @pre_change_file = qw(); my %file_seen; my $ctr = 0; foreach my $line (@file) { $ctr++; if($line =~ m|www\.test\.com|i || $line =~ m|24\.1 +30\.71\.100|i) { push (@pre_change_file, "$name"); foreach my $pre_tag_file (@pre_change_file) { next if $file_seen{ $pre_tag_file }++; #re +move duplicate files push(@change_file, $pre_tag_file); } } } } foreach my $tag_file (@change_file) { $file_count++; if ($sim eq "no") { my $replace_cmd1 = "$iwperl \"s|24.130.71. +100|24.130.71.10|g\" \"$File::Find::dir\\$name\""; # replace "24.130. +71.100" string cmd1 `$replace_cmd1`; # print "replace_cmd: $replace_cmd1\n"; # print MYFILE "replace_cmd1: $replace_cmd +1\n"; my $replace_cmd2 = "$iwperl \"s|www.test.c +om|12.130.71.10|g\" \"$File::Find::dir\\$name\""; # replace "www.test +.com" string cmd2 `$replace_cmd2`; # print "replace_cmd: $replace_cmd2\n"; # print MYFILE "replace_cmd2: $replace_cmd +2\n"; # print "FILE MODIFIED: $File::Find::dir\\ +$name\n"; # print ".BAK FILE DELETED: $path/$name\.b +ak\n\n"; # print MYFILE ".BAK FILE DELETED: $path/$ +name\.bak\n\n\n"; unlink("$File::Find::dir\\$name\.bak"); # +delete .bak file created from replace cmd1 and cmd2 } print MYFILE "FILE MODIFIED: $File::Find::dir\ +\$name\n"; $total_count = $file_count; # print "totalcount: $total_count\n"; } } } if ($file_count > 0) { # sum all files modified in all directories $total_count += $file_count; print "total files modified in \"$File::Find::dir\" directory: + $file_count\n"; # return total files per directory print MYFILE "total files modified in \"$File::Find::dir\" dir +ectory: $file_count\n"; # return total files per directory if ($total_count > 5) { goto END; } } return @files; #return the list to continue processing } sub wanted { # not used here, but dummy sub is needed for syntax # this routine is called for each file/directory # if we wanted to do something special for each one # maybe get a size or whatever... # the full path name of this file would be in $File::Find::name }

    Thanks for your reply guys. However, My server doesn't have slurp.pm so I cannot use this solution because server admin probably will not want to install this module for my work. I tried goto LABEL but count is not correct, code is not breaking out of directory at file count. It's breaking out at directory with filecount. Hence it shows total count as of file directory reached where filecunt exist.

      Please see Yes, even you can use CPAN.

      perl -E'sub Monkey::do{say$_,for@_,do{($monkey=[caller(0)]->[3])=~s{::}{ }and$monkey}}"Monkey say"->Monkey::do'