sriram_perl_diver has asked for the wisdom of the Perl Monks concerning the following question:

Hi Monks,
Firstly, I sincerely apologize for the big context
I'm struck up with an issue which I have no idea of why it occurred all of a sudden! The below code was working good until yesterday. My requirement was :
  1. Get the compressed folder (zip) or a plain folder as an argument
  2. if the argument passed is a zip file, then it should extract the contents of the zip in the current directory.
    - There is a problem in this case. When the Compressed file is zipped from a folder, it is extracting the content inside a folder with the name of zip file. i.e., if the zip file name is test.zip, the files are extracted into /test folder - This is just fine
    - But if the zip file is generated from a list of files but not from a folder, then the extraction puts all the files in the current directory
  3. After the extraction, i have to find a specific file from the extracted folder. The file would be a text file (.txt) and would have the string "index" in the filename.
use Data::Dumper; use POSIX qw(strftime); use File::Copy; if($#ARGV == -1 || $#ARGV != 0) { die("\nPlease enter the Compressed folder name along with extensio +n as an argument!\n"); exit; } my $compPackage = $ARGV[0]; my $dir = "."; my $input_dir = ''; if(index($compPackage, ".zip") != -1) { print "Extracting the ZIP package..\n"; system ("unzip -u $compPackage"); print "Extraction Completed\n"; $input_dir = substr $compPackage, 0, -4; } else { $input_dir = $compPackage; print "Folder Processed\n"; } chmod 0755, $input_dir; opendir D, $input_dir or die "Could not open dir: $!\n"; my @fileName = grep(/index/i, readdir D); if(index(@fileName, "txt") == -1) { die("Index file not found / is not valid!.\nPlease ensure the inde +x file is in the Input folder and with '.txt' extension\n"); exit; }
The issue :
  1. The difference in the folder structure of ZIP file.(i.e., files inside a folder or without a folder). I tried putting a temp folder for the extracted files. But that is causing problems when I try to access the extracted files for further processing due to the zip file structure
  2. The grep function. It was getting the file name until yesterday. Now it returns '0' or '1' according to the presence of the index txt file
Thanks in advance

Replies are listed 'Best First'.
Re: Confusion with Unzip and GREP
by Eily (Monsignor) on Dec 11, 2014 at 10:39 UTC

    Seeing how you check the length of @ARGV, you should really read the tutorial on context. That's surely where your problem with grep comes from, becauses it returns the list of matches in list context, and the number of matches in scalar context. So you certainly added a scalar context somewhere when trying to see what grep does.

    Maybe File::Find could help you on searching your file in a depth-independant way.

    Edit: by the way, your test at the beginning of the script could have been written if (@ARGV != 1), that's what makes it look like you don't understand context very well.

Re: Confusion with Unzip and GREP
by Anonymous Monk on Dec 11, 2014 at 10:29 UTC

    ... my @fileName = grep(/index/i, readdir D); ...

    ... The grep function. It was getting the file name until yesterday. Now it returns '0' or '1' according to the presence of the index txt file

    Then your code does not matches that would produce the values that you are complaining about.

    if(index(@fileName, "txt") == -1) { ... }

    index function takes two string scalars (& optionally position), not an array & a string.

Re: Confusion with Unzip and GREP
by DanBev (Scribe) on Dec 11, 2014 at 10:40 UTC
    Hi! For the second issue, I created a /tmp/index.txt file and I tried your code
    opendir D, "/tmp" or die "could not open dir: $!\n"; my @filename = grep(/index/i, readdir D); print @filename;
    Well, I get an "1" . I think it's because "grep" returns an array. Did you tried something like "$filename[0]"? This returns correctly the file name "index.txt". I dunno why yesterday it worked...maybe some editing? Hope you help.

      Poppycock!

      #!perl use strict; use warnings; use 5.010; use Data::Dumper; my @list = qw[ Xindex r-index.txt Index.txt notIdx.txt ]; my @file = grep( /index/i , @list ); say Dumper( \@file ); __END__ $VAR1 = [ 'Xindex', 'QIndex', 'r-index.txt', 'Index.txt' ];

      See Eliy's reply about grep-in-scalar-context.

        Correction: given above @list, output should have been (shortened the list while posting but failed to adjust output along the way) ...

        $VAR1 = [ 'Xindex', 'r-index.txt', 'Index.txt' ];

        Sorry Eily for I had misspelled your (pseudo)name.