Resend: using Getopt::Long with option value having spaces

S

Sunil

All,

I have a text file which has some metadata, like
----
t1.pl -frwk=perl -mode=1 -args=a,b,c -comments="This is comment 1"
t2.sql -frwk=sql -mode=2 -args=x -comments="This is comment 2"
----

I need to read this file line by line and parse it to get the values of
frwk, -mode and comments, so that I can create another string depending on
the different values for this string and pass it on to the corresponding
perl api I have which will execute it for me.

I am stuck because I am not able to pass spaces as part of comments. Is
there a workaround?


I am doing something like the following.
####################################################
my $eval_string = '@ARGV = qw (' . "$scriptOptions" . ' )' ;
eval $eval_string;
GetOptions("fwk=s" => \$framework,
"mode=s" => \$errMode,
"args=s" => \@arguments,
"comments=s" => \$comments );
####################################################

I am using GetOptions as in future the metadata file may have new or
changed options.



Thanks,
Sunil.
 
J

James Willmore

t1.pl -frwk=perl -mode=1 -args=a,b,c -comments="This is comment
1" t2.sql -frwk=sql -mode=2 -args=x -comments="This is comment 2"

Have you tried single quotes on the command-line?
ie
-comments='This is a comment'

HTH

Jim
 
J

John W. Krahn

Sunil said:
I have a text file which has some metadata, like
----
t1.pl -frwk=perl -mode=1 -args=a,b,c -comments="This is comment 1"
t2.sql -frwk=sql -mode=2 -args=x -comments="This is comment 2"
----

I need to read this file line by line and parse it to get the values of
frwk, -mode and comments, so that I can create another string depending on
the different values for this string and pass it on to the corresponding
perl api I have which will execute it for me.

I am stuck because I am not able to pass spaces as part of comments. Is
there a workaround?

I am doing something like the following.
####################################################
my $eval_string = '@ARGV = qw (' . "$scriptOptions" . ' )' ;
eval $eval_string;

That is the same as:

@ARGV = split ' ', $scriptOptions;

But without the eval(). This appears to work for your data:

$ perl -le'
$x = q/t1.pl -frwk=perl -mode=1 -args=a,b,c -comments="This is
comment 1"/;
print for $x =~ /(\S.*?\S)(?=\s+-|$)/g;
'
t1.pl
-frwk=perl
-mode=1
-args=a,b,c
-comments="This is comment 1"



John
 
S

Sunil

John W. Krahn said:
That is the same as:

@ARGV = split ' ', $scriptOptions;

But without the eval(). This appears to work for your data:

$ perl -le'
$x = q/t1.pl -frwk=perl -mode=1 -args=a,b,c -comments="This is
comment 1"/;
print for $x =~ /(\S.*?\S)(?=\s+-|$)/g;
'
t1.pl
-frwk=perl
-mode=1
-args=a,b,c
-comments="This is comment 1"


can some one please simpilify
print for $x =~ /(\S.*?\S)(?=\s+-|$)/g;
for this newbie.
 
B

Bart Lateur

Sunil said:
I have a text file which has some metadata, like
----
t1.pl -frwk=perl -mode=1 -args=a,b,c -comments="This is comment 1"
t2.sql -frwk=sql -mode=2 -args=x -comments="This is comment 2"
----

I need to read this file line by line and parse it to get the values of
frwk, -mode and comments, so that I can create another string depending on
the different values for this string and pass it on to the corresponding
perl api I have which will execute it for me.

I am stuck because I am not able to pass spaces as part of comments. Is
there a workaround?

Even though my first thought was to use Getopt::Long, too, I don't think
it's appropriate, as the data needs already to have been parsed into an
array, @ARGV, by the shell. It's that job you have to do yourself.

Your question seems related to this FAQ entry:

How can I split a [character] delimited string except when
inside [character]? (Comma-separated files)

<http://perldoc.com/perl5.8.0/pod/pe...n-inside [character]--(Comma-separated-files)>

The various quoting styles for the shell in order to embed quotes inside
quoted fields, is an extra complication. It must be possible to embed
them into the regex offered in that answer.

You might still be able to use Getopt::Long to further process the array
you get this way, though the hardwired connection with @ARGV may
complicated the call. Perhaps it's overkill to try and use it, depending
on how complex your lines actually are.
 
S

Sunil

I have a text file which has some metadata, like
That is the same as:

@ARGV = split ' ', $scriptOptions;

But without the eval(). This appears to work for your data:

$ perl -le'
$x = q/t1.pl -frwk=perl -mode=1 -args=a,b,c -comments="This is
comment 1"/;
print for $x =~ /(\S.*?\S)(?=\s+-|$)/g;
'
t1.pl
-frwk=perl
-mode=1
-args=a,b,c
-comments="This is comment 1"

can some one please simpilify
print for $x =~ /(\S.*?\S)(?=\s+-|$)/g;
for this newbie.
 
B

Bart Lateur

John said:
$x = q/t1.pl -frwk=perl -mode=1 -args=a,b,c -comments="This is
comment 1"/;
print for $x =~ /(\S.*?\S)(?=\s+-|$)/g;

Nah... what about

-comments="This includes -one, -two odditites"

IMO you really need to properly parse the quoted strings.

print for $x =~ /((?>[^"\s]+|"[^"]*")+)/g;

Works well with

$x = q/t1.pl -frwk=perl -mode=1 -args=a,b,c -comments="This
is comment 1" -comments="This contains -one, -two oddities"/;

(unwrapped)
 
S

Soren A.

Sunil (Sunil <[email protected]>) posted to [comp.lang.perl.misc]:

and Sunil came back with:
can some one please simpilify
print for $x =~ /(\S.*?\S)(?=\s+-|$)/g;
for this newbie.

This is a classic example of making it harder for other people to help
you. Very understandable though, because when people are frustrated they
don't think clearly. The OP, Sunil, needed to specify more precisely
what he didn't understand about the suggested code; a later follow-up
guessed that he didn't understand the regex construct, but I believe
it's just as possible that he didn't understand the outer perl idiom,
that is, the structure. So I am going to comment on that in hopes it
will help.

To a Perl newbie, something like "print for $x =~
/(\S.*?\S)(?=\s+-|$)/g;" is puzzling. That's because they haven't even
begun to deal with the underlying principles of Perl's notions of truth,
or the flow control elements of perl syntax (and it's OK, happens to
many of us, it takes a while).

Sunil, it's not a question of simplifying it. It's a question of
complexifying it, that is, this was a statement made in a nice, brief,
concise way -- like the way humans normally talk in daily life (when
they are not making political speeches, sermons or delivering seminars).
So, OK, to complexify it enough for you to understand it:

while( my $truth = $x =~ /(\S.*?\S)(?=\s+-|$)/g ) { print $_ if $truth; }

Is that a little better? "for" is often a more idiomatic way to say
something in perl than "while" is. And then there's the use of the
implicit "$_" var which you don't see after "print". Together, that's
Idiomatic Perl. You don't have to write Perl that way (TMTOWTDI,
presumably you are aware of that expression): but if you ask for help
from perl experts in fora like this, you will be perplexed at the advice
until you grapple with these issues I've pointed out.

It helped me to read the Camel and other perl mainstays over and over
and over again.

HTH,
Soren A
 
B

Benjamin Goldberg

Sunil said:
All,

I have a text file which has some metadata, like
----
t1.pl -frwk=perl -mode=1 -args=a,b,c -comments="This is comment 1"
t2.sql -frwk=sql -mode=2 -args=x -comments="This is comment 2"
----

I need to read this file line by line and parse it to get the values of
frwk, -mode and comments, so that I can create another string depending
on the different values for this string and pass it on to the
corresponding perl api I have which will execute it for me.

I am stuck because I am not able to pass spaces as part of comments. Is
there a workaround?

I am doing something like the following.
####################################################
my $eval_string = '@ARGV = qw (' . "$scriptOptions" . ' )' ;
eval $eval_string;

Eww. What happens if $scriptOptions happens to contain a ")" in it?

Anyway, the proper solution would be to do:

use Text::parseWords qw(shellwords);
@ARGV = shellwords($scriptOptions);
GetOptions("fwk=s" => \$framework,
"mode=s" => \$errMode,
"args=s" => \@arguments,
"comments=s" => \$comments );

This part is ok, though.
 

Ask a Question

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

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,755
Messages
2,569,538
Members
45,024
Latest member
ARDU_PROgrammER

Latest Threads

Top