Comparing a string to filenames in a directory

Discussion in 'Perl Misc' started by nj_perl_newbie, Feb 10, 2004.

  1. I apologize for posting such a basic question...I have spent a
    substantial ammount of time reading thick books trying to figure out
    how to do this.

    The goal is to read the second field in a text file and compare that
    string to a list of filenames in a directory.

    So use submits a file with "foo, test.txt" the script will look for
    "test.txt" in the directory, if it exists it will copy test.txt to a
    different directory.


    Here's what I have:

    opendir(DIR, $limbodir);
    &log_entry($logfh,"Opening Limbo Directory"); if $debug;
    @files = grep { /\.csv$/ } readdir(DIR);
    &log_entry($logfh, "Files in limbodir read") if $debug;
    closedir(DIR);

    open (FILE, "$cnfrm_file") || die();

    ($line)= <FILE>; #Read only the first line into the input file.

    while (<FILE>) { #not sure if the while is needed

    my @line = split /\,/, $_;
    my($firstfield, $filename, $junk) = @line;

    unless ( $firstline ) {
    #attempts to match the filename submitted in the confirm file with
    an already existing input file in the limbo directory
    if ( $filename) {
    ( $filename =~ m/^@files/i ) {
    &log_entry($logfh, "Confirm submitted by $username for input
    file $path/$basename ");
    move ("$_", "$transdir/$basename") || die "move failed: $!";
    &log_entry($logfh, "$_ moved to $transdir");
    chown 23456,23458, "$transdir/$_" || warn $!;
    }

    Thanks
     
    nj_perl_newbie, Feb 10, 2004
    #1
    1. Advertising

  2. nj_perl_newbie wrote:
    > I apologize for posting such a basic question...I have spent a
    > substantial ammount of time reading thick books trying to figure out
    > how to do this.
    >
    > The goal is to read the second field in a text file and compare that
    > string to a list of filenames in a directory.
    >
    > So use submits a file with "foo, test.txt" the script will look for
    > "test.txt" in the directory, if it exists it will copy test.txt to a
    > different directory.
    >
    >
    > Here's what I have:
    >


    You are missing
    use strict;
    use warnings;

    > opendir(DIR, $limbodir);
    > &log_entry($logfh,"Opening Limbo Directory"); if $debug;


    What's the ampersand doing there? Or are you still programming Perl4?
    What is the semicolon doing in the middle of the line?

    > @files = grep { /\.csv$/ } readdir(DIR);
    > &log_entry($logfh, "Files in limbodir read") if $debug;
    > closedir(DIR);


    From the program logic this whole readdir section above is not needed.
    It is much easier to use "-e" later.

    > open (FILE, "$cnfrm_file") || die();


    You may want to get into the habit of using the lower-priority "or" operator
    instead of "||".
    Also, you will get much better error messages if you include some text, the
    error code, and the file name with your die() statement:
    open (FILE, "$cnfrm_file") or die("Cannot open file $dnfrm_file because
    $!\n");

    > ($line)= <FILE>; #Read only the first line into the input file.


    Well, I would have made the comment
    # skipping first line
    because that is what you are doing.
    However, do you really want to skip the first line?

    > while (<FILE>) { #not sure if the while is needed


    Do you want to read the whole file line by line?

    > my @line = split /\,/, $_;


    No need to escape the comma. It is not a special character in a RE.

    > my($firstfield, $filename, $junk) = @line;


    Clearer in my opinion would be
    my (undef, $filename, undef) = split /,/;
    Then there is no missunderstanding about if you ever use $firstfield and
    $junk.

    > unless ( $firstline ) {


    I don't understand what you are trying to do here? Why are you testing if
    $firstline evaluates to true?

    > #attempts to match the filename submitted in the confirm file with
    > an already existing input file in the limbo directory
    > if ( $filename) {


    I don't understand what you are trying to do here, either? Why are you
    testing if $filename evaluates to true?

    > ( $filename =~ m/^@files/i ) {


    If you just want to test if a file with the name $filename exists then just
    use a simple
    if (-e $filename) {

    > &log_entry($logfh, "Confirm submitted by $username for input
    > file $path/$basename ");
    > move ("$_", "$transdir/$basename") || die "move failed: $!";
    > &log_entry($logfh, "$_ moved to $transdir");
    > chown 23456,23458, "$transdir/$_" || warn $!;
    > }


    HTH

    jue
     
    Jürgen Exner, Feb 10, 2004
    #2
    1. Advertising

  3. Thanks for the quick feedback.

    I have made some edits based on your suggestions, and I have a better
    unserstanding of what was happening in the script. I still do not
    understand how the script knows that it should compare the second
    field in the file to the filenames in the limbo dir.

    # Opens limbodir and reads the filenames for later comparison
    &log_entry($logfh,"About to open limbodir") if $debug;
    opendir(DIR, $limbodir);
    chdir("$limbodir") or die "Could not cd into $limbodir: $!\n";
    &log_entry($logfh,"Opening Limbo Directory") if $debug;
    #@files = grep { /\.csv$/ } readdir(DIR);
    #&log_entry($logfh, "Files in limbodir read") if $debug;
    #closedir(DIR);

    open (FILE, "$input_file") or die("Cannot open file $dnfrm_file
    because
    $!\n");

    while (<FILE>) { #not sure if the while is needed

    #my @line = split /\,/, $_;
    #my($firstfield, $filename, $junk) = @line;
    my (undef, $filename, undef) = split /,/;
    unless ( $firstline ) {
    #attempts to match the filename submitted in the confirm file with
    an already existing input file in the limbo directory
    if (-e $filename) {
    &log_entry($logfh, "Confirm submitted by $username for input
    file $path/$basename ");
    move ("$_", "$transdir/$basename") or die "move failed: $!";
    &log_entry($logfh, "$_ moved to $transdir");
    chown 23456,23458, "$transdir/$_" or warn $!;
    }
    undef $firstline;
     
    nj_perl_newbie, Feb 10, 2004
    #3
  4. nj_perl_newbie <> wrote:

    > I apologize for posting such a basic question...I have spent a
    > substantial ammount of time reading thick books trying to figure out
    > how to do this.



    Have you seen the Posting Guidelines that are posted here frequently?


    > Here's what I have:
    >
    > opendir(DIR, $limbodir);
    > &log_entry($logfh,"Opening Limbo Directory"); if $debug;

    ^^^^

    That is not Perl code.

    If you need help with your Perl program, then you should post
    the actual Perl program.

    If your question is about the syntax error, then you should ask
    a question about the syntax error.


    > my @line = split /\,/, $_;
    > my($firstfield, $filename, $junk) = @line;



    The @line temporary variable is not needed:

    my($firstfield, $filename, $junk) = split /\,/, $_;

    or even

    my($firstfield, $filename) = split /\,/, $_;


    > chown 23456,23458, "$transdir/$_" || warn $!;



    It is easier to work with permissions if you think in octal
    rather than in decimal...


    --
    Tad McClellan SGML consulting
    Perl programming
    Fort Worth, Texas
     
    Tad McClellan, Feb 10, 2004
    #4
  5. In article <>,
    (nj_perl_newbie) wrote:

    > Thanks for the quick feedback.
    >
    > I have made some edits based on your suggestions, and I have a better
    > unserstanding of what was happening in the script. I still do not
    > understand how the script knows that it should compare the second
    > field in the file to the filenames in the limbo dir.
    >
    > # Opens limbodir and reads the filenames for later comparison
    > &log_entry($logfh,"About to open limbodir") if $debug;
    > opendir(DIR, $limbodir);
    > chdir("$limbodir") or die "Could not cd into $limbodir: $!\n";
    > &log_entry($logfh,"Opening Limbo Directory") if $debug;
    > #@files = grep { /\.csv$/ } readdir(DIR);
    > #&log_entry($logfh, "Files in limbodir read") if $debug;
    > #closedir(DIR);
    >
    > open (FILE, "$input_file") or die("Cannot open file $dnfrm_file
    > because
    > $!\n");
    >
    > while (<FILE>) { #not sure if the while is needed
    >
    > #my @line = split /\,/, $_;
    > #my($firstfield, $filename, $junk) = @line;
    > my (undef, $filename, undef) = split /,/;
    > unless ( $firstline ) {
    > #attempts to match the filename submitted in the confirm file with
    > an already existing input file in the limbo directory
    > if (-e $filename) {
    > &log_entry($logfh, "Confirm submitted by $username for input
    > file $path/$basename ");
    > move ("$_", "$transdir/$basename") or die "move failed: $!";
    > &log_entry($logfh, "$_ moved to $transdir");
    > chown 23456,23458, "$transdir/$_" or warn $!;
    > }
    > undef $firstline;


    How about this:

    use strict;
    use warnings;

    opendir(my $dir, $limbodir) or die("could not opendir $limbodir: $!");
    my @files = grep { /\.csv$/ } readdir($dir);
    closedir($dir);

    open(my $file, "<", $dnfrm_file) or die("could not open $dnfrm_file:
    $!");

    while(<$file>) {
    chomp;
    my ($firstfield, $filename, $rest) = split /,/;
    if (defined($filename) and ($filename ne '') and
    (-e "$limbodir/$filename") {
    move("$_", "$transdir/$basename") or die("move failed: $!");
    }
    }

    I'm not too sure about some of the steps you are taking -- that move
    call seems a bit complicated -- but this might be a bit clearer...

    HTH,
    Ricky
     
    Richard Morse, Feb 10, 2004
    #5
  6. nj_perl_newbie

    Ben Morrow Guest

    wrote:
    > nj_perl_newbie <> wrote:
    > > chown 23456,23458, "$transdir/$_" || warn $!;

    >
    > It is easier to work with permissions if you think in octal
    > rather than in decimal...


    chown, not chmod... :)

    It's likely to be more future-proof if you get the [ug]id using
    get{pw,gr}nam.

    Ben

    --
    perl -e'print map {/.(.)/s} sort unpack "a2"x26, pack "N"x13,
    qw/1632265075 1651865445 1685354798 1696626283 1752131169 1769237618
    1801808488 1830841936 1886550130 1914728293 1936225377 1969451372
    2047502190/' #
     
    Ben Morrow, Feb 10, 2004
    #6
  7. Ben Morrow <> wrote:
    > wrote:
    >> nj_perl_newbie <> wrote:
    >> > chown 23456,23458, "$transdir/$_" || warn $!;

    >>
    >> It is easier to work with permissions if you think in octal
    >> rather than in decimal...

    >
    > chown, not chmod... :)



    Doh!


    --
    Tad McClellan SGML consulting
    Perl programming
    Fort Worth, Texas
     
    Tad McClellan, Feb 10, 2004
    #7
  8. nj_perl_newbie

    Tintin Guest

    "nj_perl_newbie" <> wrote in message
    news:...
    > Thanks for the quick feedback.


    Who are you talking to? Please learn how to reference, attribute and quote
    correctly.

    >
    > I have made some edits based on your suggestions, and I have a better
    > unserstanding of what was happening in the script.


    Unfortunately, you ignored most of the good suggestions.

    > I still do not
    > understand how the script knows that it should compare the second
    > field in the file to the filenames in the limbo dir.
    >


    [snip of essentially the same script as the original]
     
    Tintin, Feb 11, 2004
    #8
  9. Okay, thank you all for your suggestions. I realise that I reposted a
    couple of the same syntax errors and I apologize if that caused any
    confusion.

    Tintin: I was thanking Jurgen for his quick feedback, at the time he
    was the only person who replied to my post.

    Ricky: thanks for your help this looks like a nice suggestion

    Tad, I have not yet read the posting guidlines, I will search for them
    today. My original question wasn't really about the syntax of the
    program. I know that I had a few random ;s, I was originally asking
    how one would approach this problem using Perl's text processing
    features.

    Thank you all of your sugestions, I will play with this some more
    today.
     
    nj_perl_newbie, Feb 11, 2004
    #9
  10. Okay, this is what I ended up with:

    I get some warnings when it is run and I am still not able to run it
    in "Taint mode", but it is moving the file. I am not receiving
    e-mails so I don't think that the call to &mail is working properly.
    Any thoughts?

    sub chx_file { # moves change files associated with a confirmation
    file to the transfer directory
    #
    #
    use File::Basename;

    my($email,$csv_path,$type) = @_;

    my $input_file = &untaint_pathname($csv_path);
    my $basename = &untaint_filename( basename($input_file,"\.csv") );
    &log_entry($logfh, "sub chx_file") if $debug;
    &log_entry($logfh, "input_file is: $input_file") if $debug;

    open (FILE, "$input_file") or die("Cannot open file $input_file
    because $!\n");

    chdir($limbodir) or die "cannot cd to limbodir ($!)";
    while (<FILE>) {
    chomp;
    my ($firstfield, $filename, $rest) = split /,/;
    &log_entry($logfh, "limbo files are $limbodir/$filename");
    &log_entry($logfh, "filename is: $filename");
    if (defined($filename) and ($filename ne '') and (-e "$filename"))
    {
    move("$filename", "/export/ftp/transfer/") or die("move failed:
    $!");
    &log_entry($logfh, "File $filename moved");
    &mail(
    recipient => $email,
    subject => "BulkAdmin input file $filename queued for production.",
    body => "The BulkAdmin input file: $filename has been queued for
    production.\n\nThis file will now be stored in the transfer directory
    and will be run in production at 7:00 AM GMT \n\nAn email will be sent
    to you after results are available.\n",
    );
    }
    else {
    &log_entry($logfh, "Confirm file doesn't match any files in
    limbo directory");
    }
    }
    }
     
    nj_perl_newbie, Feb 12, 2004
    #10
  11. nj_perl_newbie

    J. Gleixner Guest

    nj_perl_newbie wrote:
    > Okay, this is what I ended up with:
    >
    > I get some warnings when it is run and I am still not able to run it
    > in "Taint mode", but it is moving the file. I am not receiving
    > e-mails so I don't think that the call to &mail is working properly.
    > Any thoughts?


    Since you're not getting "mail", it's obviously the call to mail() (note
    the absence of &) isn't working. Since you don't provide that code or
    test what mail() returns, who knows.
     
    J. Gleixner, Feb 12, 2004
    #11
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. B.J.
    Replies:
    4
    Views:
    772
    Toby Inkster
    Apr 23, 2005
  2. Psymaster
    Replies:
    3
    Views:
    788
    Psymaster
    Jun 30, 2003
  3. rtilley
    Replies:
    22
    Views:
    679
    Christos Georgiou
    Mar 2, 2006
  4. Cindy Lamma
    Replies:
    3
    Views:
    531
    Thomas Weidenfeller
    Aug 11, 2006
  5. Deepu
    Replies:
    10
    Views:
    185
    Xicheng Jia
    Mar 16, 2007
Loading...

Share This Page