Dan S.
Dan S.

Reputation: 162

perl regular expression matching more than it should -- due to shell escaping

I have a lot of files that need one line changed.

Here is the code:

GetOptions ('full' => \$full,
        'dbno=s' => \$dbno,
            'since=s' => \$since,
            'printSQL' => \$printSQL,
            'nwisDB=s' => \$nwisDBOption);

# Find the NWISDB to be extracted

if ($nwisDBOption eq '') {
  $nwisdb = &WSCExtractor::getNwisdb;
} else {
  $nwisdb = uc($nwisDBOption);
}

Here is what I want:

GetOptions ('full' => \$full,
        'dbno=s' => \$dbno,
            'since=s' => \$since,
            'printSQL' => \$printSQL,
            'nwisDB=s' => \$nwisDBOption) || &WSCExtractor::usage();

# Find the NWISDB to be extracted

if ($nwisDBOption eq '') {
  $nwisdb = &WSCExtractor::getNwisdb;
} else {
  $nwisdb = uc($nwisDBOption);
}

Here is the perl command I am using:

perl -pi -e "s/\\\$nwisDBOption\);/\\\$nwisDBOption\) || \&WSCExtractor::usage\(\);/" extractor-template

Here is the result:

GetOptions ('full' => \$full,
        'dbno=s' => \$dbno,
            'since=s' => \$since,
            'printSQL' => \$printSQL,
            'nwisDB=s' => \$nwisDBOption) || &WSCExtractor::usage();

# Find the NWISDB to be extracted

if ($nwisDBOption eq '') {
  $nwisdb = &WSCExtractor::getNwisdb;
} else {
  $nwisdb = uc($nwisDBOption) || &WSCExtractor::usage();
}

It is matching the second instance of $nwisDBOption even though it does not have a \ in front of it. I have tried adding more \ in front in case perl was eating them. It did not match then. Thanks.

Upvotes: 1

Views: 105

Answers (1)

Ilmari Karonen
Ilmari Karonen

Reputation: 50328

I'm assuming you're on a Unixish OS, not Windows. Since you're using double quotes around your code, the shell is parsing it and — among other things — replacing double backslashes with single one. So the code perl sees is actually not:

s/\\\$nwisDBOption\);/\\\$nwisDBOption\) || \&WSCExtractor::usage\(\);/

but:

s/\$nwisDBOption\);/\$nwisDBOption\) || \&WSCExtractor::usage\(\);/

You can easily confirm this by running the command:

echo "s/\\\$nwisDBOption\);/\\\$nwisDBOption\) || \&WSCExtractor::usage\(\);/"

Anyway, there are a few ways to fix the problem. The ones I'd recommend would be either to use single quotes instead double quotes, or simply to write your code into an actual Perl script file and run it that way.

However, if you really wanted to, you could just double all backslashes in your code.

Upvotes: 2

Related Questions