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

I have a file in which I store a list of file names. Often files will have $ symbols and other characters in the name:

com/eteks/awt/PJAGraphics$1.class
com/eteks/awt/PJAGraphics$2.class
com/eteks/awt/PJAGraphics$3.class
com/eteks/awt/PJAGraphics$4.class
com/eteks/awt/PJAGraphics$5.class
com/eteks/awt/PJAGraphics$AreaAveragingScaleFilter.class
com/eteks/awt/PJAGraphics$CircleQuarterListener.class
com/eteks/awt/PJAGraphics$PJAFont.class
com/eteks/awt/PJAGraphics$PJARectangle.class
com/eteks/awt/PJAGraphics.class

I have a perl script that needs to read these file names and perform some different operations on them. I read it in as:

open(FH, "$datfile") || die "Can't open $datfile!"; while(my $line=<FH>) { chomp($line); push(@list, $line); }

Is there a way to escape all special characters in an input stream so that they remain characters rather than being interpreted as scalars by the interpreter?

Thanks in advance,

jbwiv

Replies are listed 'Best First'.
Re: Reading special characters from file?
by suaveant (Parson) on Apr 26, 2001 at 16:39 UTC
    They will only be interpreted as scalars if you eval them... if a $ is in a string it is only a $... example
    $test = 'ab$cd'; print "$test\n"; #prints ab$cd\n #only when you actually have the $ in double quotes... print "ab$cd\n"; #do you need to worry about it
    Update but if you were evalling it you could do
    eval "\Q$test\E";
    the \Q \E goes through a string escaping (\$) all non word characters.
                    - Ant
Re: Reading special characters from file?
by frankus (Priest) on Apr 26, 2001 at 16:39 UTC

    Yup there are loads of ways ;-)1 Although as it's been said there are few situations when you can implicitly use them as values.
    1. quotemeta() being the most obvious.

    --
    
    Brother Frankus.

      quotemeta() did the trick. The problem was occurring because I passed the files to the shell using:

      $cmd = 'someshellexe ' . $basepath . '/' . $file; $rc = qx($cmd);

      The $ was being interpreted when passed to the shell. Changing this to:

      $cmd = 'someshellexe ' . $basepath . '/' . $file; $escapedcmd = quotemeta($cmd); $rc = qx($escapedcmd);
      worked like a charm. Thanks to all for the help!
        A hint: you can do that a bit more readably by using interpolation -- note that Perl won't doubly interpolate, even though the shell might once you pass the value to it:
        $cmd = "someshellexe $basepath/$file"; $cmd = quotemeta($cmd); $rc = qx($cmd); #
        ... unless, as I take it, $rc eq 'result code', in which case use $rc = system($cmd), unless the result code is actually in the output of the command, in which case use qx.
Re: Reading special characters from file?
by mrmick (Curate) on Apr 26, 2001 at 16:44 UTC
Re: Reading special characters from file?
by larryk (Friar) on Apr 27, 2001 at 16:14 UTC
    just slap in this extra line:
    open(FH, "$datfile") || die "Can't open $datfile!"; binmode FH; # <----- this one while(my $line=<FH>) { chomp($line); push(@list, $line); }
    which will read the file as is and not respond to any special chars. it's particularly useful if you are parsing files from another operating system which may (as in a recent project I did) contain dodgy chars like, and I'll see if I can remember correctly, ctrl-Z in a file which came from a *NIX system but on Win32 it is an EOF char and broke the while (<FH>) { blah; } loop.

    larryk