Hello Monks,
I have been introduced recently to the Getopt::Long and I was trying to create my first example by storing ARGV inputs into an array and checking for the extension '*.xls' and '*.csv' through a regex expression.
My code was copied and modified from Examples for using Getopt::Long.
Although that I am applying the same technique to the last argument of ARGV and works just fine I can not find a way to applied it also on the nth - 1 elements. The problem appears because of the -f extension to my '*.xls' files. I need to find a way to separate the -f extension from all the arguments except of the last one. Because the last one has a different extension -p. To get the last element of the ARG I am using pop function.
I observed that ARGV also take in consideration the -f and -p options that I am using as input from terminal, while I was processing the values.
If any one feels more familiar and can provide any thoughts to my problems I would be great.
UpdateMy target is to create a dynamic argument input and check one by one the arguments for '*.xls' and '*.csv' extensions. So far, my code works fine for the last argument input, but the problem appears when I am trying to check the rest of the inputs.
Sample of input: perl test.pl -f test.xls -f test-2.xls -f test-3.xls -p sample.csv. At this point I can detect the error if the user did not provide a '*.csv'. My problem is that I can not check one by one the other argument inputs and store them in the array @xls.
I modified the code based on my last update, but again I got stuck. Based on my last modification, the code compiles without any errors but it can not detect the '*.xls' elements one by one.
Expected output would be (taken in consideration the input):
$VAR1 = [ 'test.xls', 'test-2.xls', 'test-3.xls' ];
I am trying to separate the -f option of every argument input so I can extract only the files test.xls test-2.xls test-3.xls and store them into the @xls array as an output.
I am using the syntax taken from Getopt::Long (perldoc), because on the documentation says:
foo=s{1,} indicates one or more values; foo:s{,} indicates zero or more option values.
In my case I need to have at least one argument input, and the final number unknown.
Sample of working code:
Output Update#!/usr/bin/perl use strict; use warnings; use Getopt::Long(); sub usage { my $message = shift(@_); if (defined $message && length $message) { $message .= "\n" unless $message =~ /\n$/; } my $command = $0; $command =~ s#^.*/##; print STDERR ( $message, "usage: $command -f file(s).xls -p file.csv\n" ); die("\n") } my @xls; my $csv; print "This is the number of \@ARGV arguments before the process ".@AR +GV."\n"; Getopt::Long::GetOptions( 'f=s{1,}' => sub { foreach $_ (@_) { print $_ . "\n"; /\.xls$/ or die ("Invalid format for option expected -f '*.xls'\n"); push(@xls,$_); } }, 'p=s' => sub { $_ = pop @_; /\.csv$/ or die ("Invalid format for option expected -p '*.csv'\n"); $csv = $_; } ) or usage("Invalid commmand line options."); usage("The '*.xls' file(s) needs to be specified.") if scalar (@xls == 0); usage("The '*.csv' file needs to be specified.") unless defined $csv; print "Input given form \@xls: ".@xls."\n"; print "Input given form \$csv: ".$csv."\n"; =test 'f=s{1,}' => sub { foreach $_ (@_) { print $_ . "\n"; /\.xls$/ or die ("Invalid format for option expected -p '*.xls'\n"); =cut
If I execute the code with input arguments (-f test.xls -p test.csv) I get:
This is the number of @ARGV arguments before the process 4 f Invalid format for option expected -f '*.xls' Invalid commmand line options. usage: long.pl -f file(s).xls -p file.csv
Which it makes sense based on my observations. Because I can see that the inputs are collected normally but I am reading the -f as an input.I have to figure out how to read the argument inputs all apart from the last one, and then remove the -f option in order to keep only the file arguments.
I have commented the last part of my code where I am checking for the '*.xls' extension one by one the inputs. This is also a problem because of the -f option but I will deal with it after.
Thank you in advance for your time and effort reading and replying to my question.
Final Update and answer to QuestionWell I understood the problem was coming from the arguments -f. The Getopt::Long module id so nicely written that can understand based on the input "extension" -f or -p of the user (arguments) where to allocate them. So my problem was that although the input is split into two different inputs I was not able to split the arguments with -f notation. Then I thought more about it and I understood that they are still arguments. Then it was really simple, I just put 2 conditions to separate them and solved!
Solution code:
Getopt::Long::GetOptions( 'f=s{1,}' => sub { foreach $_ (@_) { if ($_ =~ /\.xls$/) { print "This is if \$_: ".$_."\n"; push( @xls , $_ ); } elsif ($_ =~ /^f/) { next; } else { die ("Invalid format for option expected -f '*.xls'\n"); } } # End of foreach }, 'p=s' => sub { $_ = pop @_; /\.csv$/ or die ("Invalid format for option expected -p '*.csv'\n"); $csv = $_; } ) or usage("Invalid commmand line options.");
Again thanks everyone time and effort to assist me.
| For: | Use: | ||
| & | & | ||
| < | < | ||
| > | > | ||
| [ | [ | ||
| ] | ] |