in reply to Parsing strings into @ARGV

CPAN suggests Text::ParseWords (found via search.cpan.org, looking for shell parse words, which pointed me to Shell::Words) - it seems to do what you want, more or less.

Replies are listed 'Best First'.
Re: Re: Parsing strings into @ARGV
by mirod (Canon) on Apr 23, 2004 at 15:23 UTC

    Thanks. Indeed it should work, and it nearly does... but it fails on one of the tests (foo\ , with an extra space at the end of the name, which is mildly annoying as I do have files that end with spaces (before anybody mentions it: no I can't change that ;--). If I quote them it works OK though (.

    It might be a bug in the module and worth fixing though.

      Yes, it's a bug. This is the offending part:
      sub shellwords { local(@lines) = @_; $lines[$#lines] =~ s/\s+$//; return(quotewords('\s+', 0, @lines)); }
      The bug is the unrestricted deletion of trailing whitespace - it shouldn't delete whitespace that's preceeded by the right number of backslashes. I'll see if I can come up with a patch later tonight.

      Note that that's not the only case where Text::ParseWords and my shell (bash) disagrees. Given the string "foo\'bar", my shell parses that as foo\'bar, while Text::ParseWords turns it into foo'bar.

      Abigail

        Yes, I saw that, here is my fix:

            $lines[$#lines] =~ s{(\\.)?\s*$}{defined $1 ? $1 : ''}e;

        I don't really like it but it passes my tests.:

        #!/usr/bin/perl -w use strict; use Test::More qw(no_plan); while( <DATA>) { my( $input, $expected)= m{^'(.*?)'\s*=>\s*'(.*?)'}; (my $trimmed= $input)=~ s{(\\.)?\s*$}{defined $1 ? $1 : ''}e; is( $trimmed, $expected, "'$input'"); } __DATA__ 't' =>'t' 't ' =>'t' 't\ ' =>'t\ ' 't\ ' =>'t\ ' 't\ \ '=>'t\ \ '

        bash, sh, csh and tcsh all give foo\'bar. This one looks more of a pain to fix.

        Are there tests for Text::ParseWords somewhere? The CPAN version has nothing, which makes it quite dangerous to work on it.