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

I have a simple file as such:

30: 400 650 710

I have a one-liner that removes the number before the colon and substitutes any following number with this removed number.

Here is the one liner:

perl -p -e 's/^([0-9]+)://g;$a=$1;s/\d+/$a/g' $CONF_FILE
I run on Solaris9 and here is what I get (the desired result):

 30 30 30

On RHAS I get nothing returned. From intial debugging it appears the number before the colon is removed but not captured.

I say this because I try this modified one-liner to print the captured result:

perl -p -e 's/^([0-9]+)://g;print $1' $CONF_FILE
On SUN I see the value printed (before the returned line of course):

30 400 650 710

But on Linux I do not see the captured value:

 400 650 710

I need this to be portable - if anyone would be gracious enough to bestow any ideas upon me I would appreciate it very much!

Edited by planetscape - added code tags

Replies are listed 'Best First'.
Re: One Liner works on SUN but not on Linux??
by samtregar (Abbot) on Nov 07, 2005 at 18:00 UTC
    Does it work on the linux machine if you do this first:

       $ export LANG=C

    If it does, upgrade your Perl. Redhat shipped a broken combination of Perl and a UFT-8 locale in several releases. It caused all kinds of problems, including breaking some regexes.

    -sam

Re: One Liner works on SUN but not on Linux??
by Perl Mouse (Chaplain) on Nov 07, 2005 at 17:24 UTC
    That's not something I can replicate on Red Hat, using perl 5.8.6. Sounds like a bug to me. Do you run the same version of Perl on both machines? And your data file contains the same?
    Perl --((8:>*
Re: One Liner works on SUN but not on Linux??
by jasonk (Parson) on Nov 07, 2005 at 17:28 UTC

    Are you sure the configuration file is exactly the same on both platforms? The only obvious problem I see with it is that you don't check if the s/// succeeds, so you could be stomping all over your variables when there is nothing to substitute. (Well, that and the fact that you are using $a as a temporary variable, when it has a reserved meaning. It's not a good idea, but it should still work.)

    perl -p -e 'if(s/^(\d+)://g) { my $x = $1; s/\d+/$x/g; }' foo.txt

    This code works as you expect it to on my Red Hat machines, but then so does your original code.

    You might try running cat -vet on your configuration files on each host, to make sure they don't contain anything you didn't expect. I would also try setting LANG=C before running it on linux, to see if your configuration file contains something odd that is getting messed up because Red Hat is setting the default LANG to utf-8.


    We're not surrounded, we're in a target-rich environment!
Re: One Liner works on SUN but not on Linux??
by sauoq (Abbot) on Nov 07, 2005 at 17:27 UTC

    This should work. If it doesn't it is almost certainly user error. I'd double check your quoting first. If, for instance, you used double quotes around your code, you would see that behavior (in both cases, I think) in the second case.

    BTW, not that it matters, but you shouldn't need a /g on your first substitution.

    -sauoq
    "My two cents aren't worth a dime.";