gagneet
gagneet

Reputation: 37259

How do I replace a set of words in a file with another set in Perl?

My requirement is to replace a set of words in a given text file with a second set of words, which might be given from the command line or another file. Wanting to use Perl to do this, as the rest of my code is also in Perl.

So, if I have the following:

server name="${server1}" host="abc.com"
server name="${server2}" host="webcs.com"
server name="${server5}" host="httpvcs1.com"
server name="${server6}" host="xyz.com"
server name="${server7}" host="msg.com"

I wish to replace the strings 'server1', 'server2', 'server5', etc, with a different set of words. These might be placed in another file or given from the command line (whichever is more feasible).

Also, if, instead of just 'server1', 'server2', etc, I want to replace the 'server' word with say 'file', how would i go about making a regex for this replacement?

perl -pie 's/server\d{1-3}/myword/g' loginOut.txt > loginOut1.txt

The above will do a replacement for all words with 'myword'. But I want only the substring to be replaced.

Upvotes: 3

Views: 1679

Answers (6)

Brad Gilbert
Brad Gilbert

Reputation: 34120

You may want to try out Template Toolkit.


Here's an excerpt from the Template Toolkit Intro, Manual page:


The Template Toolkit is a collection of Perl modules which implement a fast, flexible, powerful and extensible template processing system. It is most often used for generating dynamic web content, although it can be used equally well for processing any kind of text documents.

At the simplest level it provides an easy way to process template files, filling in embedded variable references with their equivalent values. Here's an example of a template.

Dear [% name %],

It has come to our attention that your account is in 
arrears to the sum of [% debt %].

Please settle your account before [% deadline %] or we 
will be forced to revoke your Licence to Thrill.

The Management.

By default, template directives are embedded within the character sequences [% ... %] but you can change these and various other options to configure how the Template Toolkit looks, feels and works. You can set the INTERPOLATE option, for example, if you prefer to embed your variables in Perl style:

Dear $name,

It has come to our attention that your account is in 
arrears to the sum of $debt.

Perldoc page

Upvotes: 0

Sudden Def
Sudden Def

Reputation: 10411

Try the following:

$what = 'server'; # The word to be replaced
$with = 'file';   # Replacement
s/(?<=\${)$what(?=[^}]*})/$with/g;

Upvotes: 0

Xetius
Xetius

Reputation: 46794

You would simply need to take as much as you require to make it unique for your situation.

In this case you could do:

s/{server/{file/g;

Upvotes: 1

Tuminoid
Tuminoid

Reputation: 9715

All the answers above have some flaw. You asked some way to

I wish to replace 'server1', 'server2', 'server5', etc. with something like 'file1', 'file2', 'file5', ..

The command for that is (in Windows prompt its -pe, not -pie):

perl -pe "s/\{server/\{file/g" in.txt > out.txt

and out.txt is:

server name="${file1}" host="abc.com"
server name="${file2}" host="webcs.com"
server name="${file5}" host="httpvcs1.com"
server name="${file6}" host="xyz.com"
server name="${file7}" host="msg.com"

I believe this is exactly what you wanted based on your latest comment.

Upvotes: 1

user44511
user44511

Reputation: 2851

The regular expression for your second question would be s/server/myword/g;. That matches (and substitutes) any occurrence of "server".

To replace server1, server2, etc., with a different string each, you could have a text file that contains the replacement rule, e.g.:

server1 abcd
server2 bcde
server3 cdef
etc.

You would then read in the date from the file into a hash, for instance,

my %dict;
while(<DICTFILE>){
    /(\S+)\s+(\S+)/;
    $dict{$1}={$2};
}

and after that proceed with the replacement:

while(my $line = <>){
    foreach my $s (keys %dict){
        $line =~ s/$s/$dict{$s}/g;
    }
    print $line;
}

Upvotes: 2

George Stocker
George Stocker

Reputation: 57877

Change your Regex to the following:

perl -pie 's/\{server/myword/g' loginOut.txt > loginOut1.txt

Upvotes: 0

Related Questions