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

Hi,

I am trying to use the following combination of Unix commands from perl.
(the combination works fine at the unix prompt):
ls -r1 *BC*.txt | grep -v Liver |awk '{split ($1,name,".");\ printf name[1]"\n"}' > BCfile.name

however when I use the same command in perl
system("ls -r1 *BC*.txt | grep -v Liver |awk '{split ($1,name,".");\ printf name[1]"\n"}' > BCfile.name");

Perl complains:
Backslash found where operator expected at new.perl line 6, near ""); +printf name[1]"\" (Missing operator before \?) syntax error at new.perl line 6, near ""); printf name[1]"\" String found where operator expected at new.perl line 6, near "n"}' > +BCfile.name""
I guess it has something to do with the use of "" inside the '' marks
I would appreciate your help!
Thank you,
Ioana

Replies are listed 'Best First'.
Re: system call in Perl
by antirice (Priest) on Jul 10, 2003 at 04:04 UTC

    q is your friend.

    system(q~ls -r1 *BC*.txt | grep -v Liver |awk '{split ($1,name,".");\ printf name[1]"\n"}' > BCfile.name~);

    antirice    
    The first rule of Perl club is - use Perl
    The
    ith rule of Perl club is - follow rule i - 1 for i > 1

Re: system call in Perl
by graff (Chancellor) on Jul 10, 2003 at 06:53 UTC
    The direct question has been answered (use the "q" operator), but as for the other question that has been hinted at, you could use perl to do some or all of what your system call is doing:
    # use an all-perl approach: opendir( DIR, "." ); @files = sort {$b cmp $a} grep /BC.*?\.txt$/, readdir DIR; close DIR; open( OUT, ">BCfile.name" ); for ( grep !/Liver/, @files ) { s/\..*/\n/; print OUT; } close OUT; # OR... a little bit of reliance on a sub-shell is okay too; # the next four lines do the same thing just as well: @files = map {s/\..*//; $_} grep !/Liver/, `ls -r *BC*.txt`; open OUT, ">BCfile.name"; print OUT join "", @files; close OUT;
    And of course, an all-command-line solution could be made easier by avoiding "awk":
    ls -r *BC*.txt | grep -v Liver | cut -f1 -d. > BCfile.name
    (Look Ma! No quotes!)

      Just to add to this: not only do you get rid of the quotes but it will probably work faster.


      Peter L. BergholdBrewer of Belgian Ales
      Peter@Berghold.Netwww.berghold.net
      Unix Professional
Re: system call in Perl
by sauoq (Abbot) on Jul 10, 2003 at 04:05 UTC

    Exchange your double quotes for q( ) and that should do it.

    system( q( ls -r1 *BC*.txt | grep -v Liver |awk '{split ($1,name,"."); +\ printf name[1]"\n"}' > BCfile.name" ) );

    Of course, you might want to question why you are going to all the trouble to write shell code in perl...

    -sauoq
    "My two cents aren't worth a dime.";
    
Re: system call in Perl
by The Mad Hatter (Priest) on Jul 10, 2003 at 04:06 UTC
    If you really want to use that command line, try using:
    system(q[ls -r1 *BC*.txt | grep -v Liver |awk '{split ($1,name,"."); p +rintf name[1]"\n"}' > BCfile.name]);
    Note the use of q and removal of the line continuation \.

      There's no need to remove the "continuation \". Of course, he didn't really need it in the first place as it occurs between single quotes (and between awk statements), but that's beside the point. He might as well keep it readable by breaking up the long line.

      -sauoq
      "My two cents aren't worth a dime.";
      
        Well, yes, but my point was that it wasn't needed. IMHO, it only improves readability slightly.