Find the answer to your Linux question:
Results 1 to 3 of 3
Hi, I'm trying to replace a load of 14400's in my zone files with 600's... Code: perl -pi.bak -e "s/( |\s)14400( |\s)/$1600$2/g if /^\s*\$TTL/" /var/named/zonefile.db The above isn't working - ...
  1. #1
    Just Joined!
    Join Date
    Dec 2008
    Posts
    19

    Help with Perl Search and Replace - Backreferences

    Hi, I'm trying to replace a load of 14400's in my zone files with 600's...

    Code:
    perl -pi.bak -e "s/( |\s)14400( |\s)/$1600$2/g if /^\s*\$TTL/" /var/named/zonefile.db
    The above isn't working - I don't know how to use backreferences in this context...

    I basically only want to replace instances of 14400 with 600 where it is immediately surrounded by whitespace characters.

    Please need help !!!!

  2. #2
    Trusted Penguin Cabhan's Avatar
    Join Date
    Jan 2005
    Location
    Seattle, WA, USA
    Posts
    3,230
    So the first thing that I notice is that indeed, your backreferences are incorrect. In particular, the bit of code "$1600$2" is interpreted by Perl to mean "the variable $1600 and the variable $2". For what you want, the line should be "${1}600$2": this explicitly states that $1 is a variable, 600 is a literal, and $2 is a variable.

    The first thing I will tell you is that your regular expression is a bit too complicated. "\s" matches a space, so ( |\s) is redundant. Let's simplify your regex a bit:
    Code:
    s/(\s)14400(\s)/$1600$2/g
    However, there is actually a better way to do this. The way that we do this is by using a Perl-specific regular expression feature called lookaheads and lookbehinds. These allow you to check for things in your pattern without actually matching against them.

    For instance, we can change your line to the following:
    Code:
    s/(?<=\s)14400(?=\s)/600/g
    This regular expression means "replace 14400 with 600 whenever the 14400 has space on both sides of it". The spaces will NOT be replaced: this regular expression does not match the spaces. It simply puts a restriction on which 14400s will be matched.
    DISTRO=Arch
    Registered Linux User #388732

  3. #3
    Just Joined!
    Join Date
    Dec 2008
    Posts
    19
    Cabhan, you're an absolute star... I have read and tried to understand some very dry explanations of lookahead and lookbehind - but learning by example is always key (for me anyway) in allowing the penny to drop!

    I also read somwhere that \s only subs for \t\f\n\r - I thought it odd that it didn't also sub for a plain old space! Obviously a duff source of info.

    My regex is now working like a charm... Now I just have to migrate a whole load of cpanel accounts to a new server

    All the best

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
...