-1

I am creating a script that I open inside of a specific folder, containing two different types of files. 'Secure' (secure.text, secure.001.text, etc.) files, and 'message' (message.txt, etc) files. Each file contains a log for the year, day, date, hour, and minute. I would like to be able to scan these files and create a new file that contains all log entries for January 2006. The purpose of this script is to be able to only scan one set of data (secure), and not all of it (messages).

I am having issues with my script finding the current working directory. To my understanding, perl will use the location of the script as the current directory. I am using the opendir and closedir functions, and getting prompted that there are 60 files within the directory of the script, but when I delete some files just to test it, it still says 60, leading me to believe that this is not using the current directory. It also is not finding 'secure', despite the correct regex.

The output I am getting is "Issue finding file 'secure'."

#!/usr/bin/perl


use strict;
use warnings;



#Locate and scan all of the files 

 #list all files in same dir as this perl script.
 my $dirname = "."; 
 opendir( my $dh, $dirname ) #sets $dh as the current working directory
    or die "Can't open dir '$dirname':$!\n"; #Kills if can not open current directory.
 my @all_the_file; #Instantiates new variable that accounts for all of the files in the current dir.
 while( my $file = readdir($dh) ) { #$file accounts for every file on device. 
    push( @all_the_file, $file ); #Pushes files in current directory to $file.

 }
 closedir( $dh ); 

 #Gets all of the secure files. 

 my @all_the_secure_file;
 @all_the_secure_file = grep(/^secure(\.\d{1,2})?$/, @all_the_file);

 #Itterate over secure files. 

my $filename = "secure";
open( my $fhin, "<", $filename)
    or die "Can't open '$filename':$!\n";
chomp( my @lines = <$fhin> ) ;
close($fhin);

 #Match the Regex of Jan. 

 my @jan_lines = grep( /^Jan/ , @lines ) ;
print "The file '$filename' = " . @lines . " lines.\n";
print "Size of \@jan_lines = " . @jan_lines . "\n";

 #Print and create new file with Data. 

 my $filename2 = "secure.1";
open( my $fhin, "<", $filename)
    or die "Can't open '$filename':$!\n";
chomp( my @lines2 = <$fhin> ) ;
close($fhin);

my @jan_lines2 = grep( /^Jan/ , @lines2 ) ;
print "The file '$filename2' = " . @lines2 . " lines.\n";
print "Size of \@jan_lines2 = " . @jan_lines2 . "\n";

 exit;
  • The location of the script is not necessarily the current working directory. The current working directory is the current working directory. Check out the [Cwd](http://perldoc.perl.org/Cwd.html) and [FindBin](http://perldoc.perl.org/FindBin.html) modules, for example. – Matt Jacob Mar 27 '17 at 22:22
  • Also, "iterate over secure files" and "print and create new file with data" don't actually do what the comments say they do... – Matt Jacob Mar 27 '17 at 22:30
  • Basic debugging: (1) Set `$dirname` to the actual path (hard-code it) (2) What you get from `opendir` does not have the path! So, prepend `$dirname` to what `opendir` returns. // Then you'll be scanning files in that `$dirname`. // Please do not _delete files_ to test! Why not just print them to screen and inspect whether they are correct? Remember, they need to have the full path. You can also test with `if (not -f $file) { print "No $file\n" }` and you'll see whether those _strings_ (name `$file`) are actual files on the system. // There are other issues but this is a start. – zdim Mar 27 '17 at 22:40
  • How do I make it so that the current working directory is the one that the script is ran from? That is essentially the main focus of this, so that I can change the name of the file in the script and have a program to organize files for me. – Matthew Parise Mar 27 '17 at 23:57
  • 1
    Did you read the links I included in my comment above? – Matt Jacob Mar 28 '17 at 00:22
  • Possible duplicate of [How do I get the full path to a Perl script that is executing?](http://stackoverflow.com/questions/84932/how-do-i-get-the-full-path-to-a-perl-script-that-is-executing) – Matt Jacob Mar 28 '17 at 00:24
  • @MatthewParise As Matt Jacob told you, see the links he posted. You can use `FindBin` to find the script's directory, `Cwd` to see what you current working directory is, and [chdir](https://perldoc.perl.org/functions/chdir.html) to change it. There are indeed numerous SO posts on these things. – zdim Mar 28 '17 at 06:22

1 Answers1

1

You really should employ some module. The following example is using Path::Tiny.

use 5.014;
use warnings;
use Path::Tiny;

my $root = path("/some/path");
my $iter = $root->iterator({recurse => 1});

while(my $path = $iter->()) {
    next unless $path->basename =~ /(secure|message)\.(\d+)?\.txt/i;

    my $type = $1;
    #my $num = $2; #???

    my @lines = grep { /^Jan/ } $path->lines();
    say "in the $path is ", scalar @lines, " lines for Jan";

    my $new = path( ($type =~ /secure/i) ? "/some/where/secure.txt" : "/some/nosecure/message.txt" );
    $new->spew(@lines);
}

Not tested, but it should do +- the same as your script, even more because it searching recurseively...

clt60
  • 62,119
  • 17
  • 107
  • 194
  • is path("/some/path"); setting the default path to where the file is? – Matthew Parise Mar 27 '17 at 23:59
  • 1
    @MatthewParise If by "_default path_" you mean the full path, yes it is. If it is essential for you to use the path relative to where the script is running, you can find that using `FindBin` (and `Cwd`) and then build its full path, and then you can still use this great module. This answer gives you pretty much all you can need, and a blueprint for future uses as well. – zdim Mar 28 '17 at 06:27
  • @MatthewParise Um ... sorry, `path($dir)` constructs an object for file/directory at `/some/path`. It is here assigned to `$root`and after that you can call module's methods on `$root`. The `path()` takes the full path to file/directory, which is what `/some/path` is (this is what I meant in the above comment). – zdim Mar 28 '17 at 07:25