Take the 2-minute tour ×
Super User is a question and answer site for computer enthusiasts and power users. It's 100% free, no registration required.

So I have a file test.txt, that contains,

home -> range

If I edit the file in vim and run the command %s/^\(.*\)->\(.*\)$/\2 ::= \1 ;/g it converts the file to

range ::= home  ;

which is what I want. However if I run

 perl -pi -e 's/^\(.*\)->\(.*\)$/\2 ::= \1 ;/g' test.txt

which I think should do the same, I get no change - can someone tell me what's gone wrong? I suspect that something needs escaping but I've thrown all manner of combinations of escape at it... plus I'd like some general rules about the conversion between the two formats...

share|improve this question

1 Answer 1

up vote 0 down vote accepted

In Perl you dont escape the capturing brackets, also it is conventional to use $1,$2 instead of \1,\2 for the capturing variables.

perl -pi -e 's/^(.*)->(.*)$/$2 ::= $1 ;/g' test.txt

It is an unfortunate fact of life that the regexes (RE) used in many common tools (vim, sed, awk, perl) are all subtly different. Some tools have an option to use Perl REs, POSIX Basic REs (BRE) or POSIX Extended REs (ERE).


perldoc perlre has this to say on $1 vs \1 in the replacement part of a substitution expression

Some people get too used to writing things like:

$pattern =~ s/(\W)/\\\1/g;

This is grandfathered for the RHS of a substitute to avoid shocking the sed addicts, but it's a dirty habit to get into. That's because in PerlThink, the righthand side of an "s///" is a double-quoted string. "\1" in the usual double-quoted string means a control-A. The custom- ary Unix meaning of "\1" is kludged in for "s///". However, if you get into the habit of doing that, you get yourself into trouble if you then add an "/e" modifier.

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.