Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Perl > Perl Misc > string substitution problem

Reply
Thread Tools

string substitution problem

 
 
Dawn Schepleng
Guest
Posts: n/a
 
      10-15-2003

Hi

I am a novice Perl programmer, and have encountered the following problem.
I can make the following string substitution work:

$high_level_dir = "/ceswbl2/installed/bin"
$low_level_dir = "/ceswbl2/src/sparc/bin";
$line =~ s{$low_level_dir(/\w+)+/(\w+)}{$high_level_dir/$2};

This will correctly take a line like:

/ceswbl2/src/sparc/bin/cec_sim/radar/sps48/cecsimlm

and make substitutions such that $line then equals:

/ceswbl2/installed/bin/cecsimlm.

I'm using \w+ to represent a word with numbers and underscores, and am
using "(", ")", and "/" to be literal, and using the substitution format of
"s{}{}" vice "s///" to be more readable.

However, when I take this working perl substitution and try to invoke it as a
system call like:

system("perl -pi -e 's{$low_level_dir(/\w+)+/(\w+)}{$high_level_dir/$2}'
$real_run_file");

It no longer works. The error occurs in a first-pass parse of the perl script,
and says something line "Unrecognized escape \w passed through
in cepSetGoEnv.pl at line 31".

With the help of a co-worker, we've tried changing "{" "}" to "|" and we've
also tried escaping out the "(" and ")" with no luck.

What is the subtle detail that makes this work in-line, but not when the script
is run w/i the system call?

Any ideas would be appreciated!

Thanks,

Dawn Schepleng
JHU/APL

 
Reply With Quote
 
 
 
 
Jeff 'japhy' Pinyan
Guest
Posts: n/a
 
      10-15-2003
[posted & mailed]

On Wed, 15 Oct 2003, Dawn Schepleng wrote:

>$high_level_dir = "/ceswbl2/installed/bin"


Missing semicolon, by the way.

>$low_level_dir = "/ceswbl2/src/sparc/bin";
>$line =~ s{$low_level_dir(/\w+)+/(\w+)}{$high_level_dir/$2};


That works as expected, which is good.

>system("perl -pi -e 's{$low_level_dir(/\w+)+/(\w+)}{$high_level_dir/$2}'
> $real_run_file");
>
>It no longer works. The error occurs in a first-pass parse of the perl
>script, and says something line "Unrecognized escape \w passed through in
>cepSetGoEnv.pl at line 31".


Right. You've made a double quoted string "perl -pi ..." and it has
backslashed characters in it. In a *regex*, \w means something. In a
double-quoted string, it doesn't. You'll need to DOUBLE the backslash.

print "m/(\\w+)/"; # prints: m/(\w+)/

The other problem you'll encounter is that Perl interpolates $2 when you
make that string you pass to system(). You don't want Perl to do that;
you want Perl to send the literal string '$2' to the system() command so
that when system() runs perl, perl sees $2.

system("perl -pi -e 's{foo(/\\w+)+(/\\w+)}bar\$2}' file");

But here's the nice thing: you don't need to call system() here. The -p
and -i flags just add wrappers around the code you give. If you know what
those wrappers look like, you can write a program that DOES what -pi does.
They're explained in the 'perlrun' manpage:

perldoc perlrun

I'm pretty sure there's an exact example of how to do what -pi does in
your program. Look for the documentation of the -i switch.

--
Jeff Pinyan RPI Acacia Brother #734 2003 Rush Chairman
"And I vos head of Gestapo for ten | Michael Palin (as Heinrich Bimmler)
years. Ah! Five years! Nein! No! | in: The North Minehead Bye-Election
Oh. Was NOT head of Gestapo AT ALL!" | (Monty Python's Flying Circus)

 
Reply With Quote
 
 
 
 
Tassilo v. Parseval
Guest
Posts: n/a
 
      10-15-2003
Also sprach Purl Gurl:

> Jeff Pinyan wrote:
>
>> Dawn Schepleng wrote:

>
> (snipped)
>
>> system("perl -pi -e 's{foo(/\\w+)+(/\\w+)}bar\$2}' file");

>
>
> Under both perl 5.6 and perl 5.8 this still cops an error message:
>
> "Can't do inplace edit without backup."
>
> Perhaps this is a bug with cygwin / win32 ports?


Partly. It's mainly a limitation of Win32 that doesn't allow altering an
already open file (unless of course you open it solely for changing the
file).

A fix would be to have perl make changes to a temporary copy of the
original file and afterwards do a rename when the -i switch is employed.
So far the user has to do that on his own.

Tassilo
--
$_=q#",}])!JAPH!qq(tsuJ[{@"tnirp}3..0}_$;//::niam/s~=)]3[))_$-3(rellac(=_$({
pam{rekcahbus})(rekcah{lrePbus})(lreP{rehtonabus}) !JAPH!qq(rehtona{tsuJbus#;
$_=reverse,s+(?<=sub).+q#q!'"qq.\t$&."'!#+sexisexi ixesixeseg;y~\n~~dddd;eval
 
Reply With Quote
 
Big and Blue
Guest
Posts: n/a
 
      10-15-2003
Jeff 'japhy' Pinyan wrote:

> The other problem you'll encounter is that Perl interpolates $2 when you
> make that string you pass to system(). You don't want Perl to do that;
> you want Perl to send the literal string '$2' to the system() command so
> that when system() runs perl, perl sees $2.
>
> system("perl -pi -e 's{foo(/\\w+)+(/\\w+)}bar\$2}' file");
>


Also, Perl will (or may) pass that through a shell. If you don't
want to deal with ensuring things aren't interpreted by the shell as
well, then pas system a LIST of arguments, rather than a single string.



--
-*- Just because I've written it here doesn't -*-
-*- mean that you should, or I do, believe it. -*-

 
Reply With Quote
 
Gunnar Hjalmarsson
Guest
Posts: n/a
 
      10-15-2003
Tassilo v. Parseval wrote:
> Also sprach Purl Gurl:
>> Under both perl 5.6 and perl 5.8 this still cops an error
>> message:
>>
>> "Can't do inplace edit without backup."
>>
>> Perhaps this is a bug with cygwin / win32 ports?

>
> Partly. It's mainly a limitation of Win32 that doesn't allow
> altering an already open file (unless of course you open it solely
> for changing the file).


Does that mean that if a Perl program, that makes use of flock() on
*nix platforms, is run on a Windows platform with flock() disabled,
you still don't need to worry too much about files being corrupted
because of concurrent changes?

--
Gunnar Hjalmarsson
Email: http://www.gunnar.cc/cgi-bin/contact.pl

 
Reply With Quote
 
Gunnar Hjalmarsson
Guest
Posts: n/a
 
      10-15-2003
Purl Gurl wrote:
> Gunnar Hjalmarsson wrote:
>> Tassilo v. Parseval wrote:
>>> Win32 ... doesn't allow altering an already open file (unless
>>> of course you open it solely for changing the file).

>>
>> Does that mean that if a Perl program, that makes use of flock()
>> on *nix platforms, is run on a Windows platform with flock()
>> disabled, you still don't need to worry too much about files
>> being corrupted because of concurrent changes?

>
> No. Concurrent writes under Win32 are a problem which must be
> addressed via semaphore locking or one of my locking mechanisms
> presented at my website.


Okay, that's what I thought. Suppose my conclusion out from Tassilo's
statement was far too extensive.

Btw, flock() works on some Win32 systems. As far as I have understood,
the need for using some other locking method is limited to Windows 95
and 98.

<snip>

> Perl does not honor "permission denied" under Win32. Locking
> mechanisms are critical to prevent concurrent writes under Win32
> when using Perl.


Thanks for clarifying.

--
Gunnar Hjalmarsson
Email: http://www.gunnar.cc/cgi-bin/contact.pl

 
Reply With Quote
 
Jeff 'japhy' Pinyan
Guest
Posts: n/a
 
      10-15-2003
On Wed, 15 Oct 2003, Purl Gurl wrote:

>system("perl -i.bak -e 's/gurlpurl/purlgurl/e' test.txt") or die "FUBAR $!";
>
>Use of a die causes a script to die at that line but does
>not generate any error message.


That's because system() returns false on success, not on failure. You
should either do

system(...) and die "...";

or

system(...) == 0 or die "...";

--
Jeff Pinyan RPI Acacia Brother #734 2003 Rush Chairman
"And I vos head of Gestapo for ten | Michael Palin (as Heinrich Bimmler)
years. Ah! Five years! Nein! No! | in: The North Minehead Bye-Election
Oh. Was NOT head of Gestapo AT ALL!" | (Monty Python's Flying Circus)

 
Reply With Quote
 
Tad McClellan
Guest
Posts: n/a
 
      10-16-2003
Jeff 'japhy' Pinyan <(E-Mail Removed)> wrote:

> You
> should either do
>
> system(...) and die "...";
>
> or
>
> system(...) == 0 or die "...";



or:

!system(...) or die "...";


Which is what I use, because I'm already used to
writing "somefunc() or die".


--
Tad McClellan SGML consulting
http://www.velocityreviews.com/forums/(E-Mail Removed) Perl programming
Fort Worth, Texas
 
Reply With Quote
 
Dave Saville
Guest
Posts: n/a
 
      10-16-2003
On Wed, 15 Oct 2003 14:12:49 -0700, Purl Gurl wrote:

>Mostly true. WinME is also in there. This problem with flock will
>appear anytime a "Win32 System" is used. This does not exclude
>WinNT5 completely. Possibly OS/2 exhibits this problem, not sure.
>Other candidates would be systems using DR-DOS or IBM DOS.


FYI flock() works on OS/2, at least with v5.8.0 - Some time ago I
tested with two scripts as I had the same problem - cgi updating a
common file. One script held an exclusive lock on a file and then
waited on keyboard input - the other tried to get the lock and said
when it did. The latter script just hung until I replied to the first
and it released the lock.

Regards

Dave Saville

NB switch saville for nospam in address


 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Re: Raw string substitution problem Gabriel Genellina Python 13 01-02-2010 06:56 AM
Re: Raw string substitution problem Ed Keith Python 3 12-16-2009 07:54 PM
Raw string substitution problem Ed Keith Python 1 12-16-2009 02:36 PM
named scope lambda string substitution problem jdwy Ruby 6 11-08-2008 07:25 PM
Q: string substitution in a file Troll Perl 6 09-26-2003 01:50 PM



Advertisments