Steven
Steven

Reputation: 335

How to search and replace string in a file in Perl

The content of my input file is shown below:

abc\**def\ghi**\abc\!!!!!
abc\**4nfiug\frgrefd\gtefe\wf4fs**\abc\df3gwddw
abc\**eg4/refw**\abc\f3

I need to replace whatever string in between abc \ --------------\abc in my input file with ABC\CBA.

I have tried something like below to get the strings that need to be replaced. But I get stuck when I need to use the search and replace:

my $string1 = qr/abc\W+([^a]+)/;
my $string2 = map{/$string1/ => " "} @input_file; # The string that needs to be replaced
my $string3 = 'ABC\CBA'  # String in that. I want it to replace to

s/$string2/$string3/g

How can I fix this?

Upvotes: 4

Views: 44895

Answers (5)

Mike M
Mike M

Reputation: 4436

#!/usr/bin/perl
use strict;
use warnings;

open my $fh,"<", "tryit.txt" or die $!;

while (my $line = <$fh>) {
    $line =~ s/(abc\\)(.*?)(\\abc)/$1ABC\\CBA$3/;
    print $line;
}

gives the following with the input data.

abc\ABC\CBA\abc\!!!!!
abc\ABC\CBA\abc\df3gwddw
abc\ABC\CBA\abc\f3

Upvotes: 1

michael501
michael501

Reputation: 1482

perl -i -pe 's/this/that/g;'  file1

Upvotes: 12

Joel Berger
Joel Berger

Reputation: 20280

To address your comment about replacing text "inplace" in the file directly, you can use the -i switch for a one-liner. In a script, you can perhaps look at using Tie::File, which allows read-write access to lines of a file as (mutable) elements in an array. To copy Mike/TLP's answer:

#!/usr/bin/perl
use strict;
use warnings;

use Tie::File;

tie my @file, "Tie::File", "tryit.txt" or die $!;

# I think you have to use $_ here (done implicitly)
while (@file) {
    s/(abc\\)(.*?)(\\abc)/$1ABC\\CBA$3/;
    print;
}

Upvotes: 1

TLP
TLP

Reputation: 67910

A one-liner to fix a file:

perl -plwe 's/abc\\\K.*(?=\\abc)/ABC\\CBA/' input.txt > output.txt

Or as a script:

use strict;
use warnings;

while (<DATA>) {
    s/abc\\\K.*(?=\\abc)/ABC\\CBA/;
    print;
}

__DATA__
abc\**def\ghi**\abc\!!!!!
abc\**4nfiug\frgrefd\gtefe\wf4fs**\abc\df3gwddw
abc\**eg4/refw**\abc\f3

The \K (keep) escape sequence means these characters will not be removed. Similarly, the look-ahead assertion (?= ... ) will keep that part of the match. I assumed you only wanted to change the characters in between.

Instead of \K one can use a look-behind assertion: (?<=abc\\). As a personal preference, I used \K instead.

Upvotes: 2

choroba
choroba

Reputation: 242218

If you do not want the substitution to operate on the default variable $_, you have to use the =~ operator:

#!/usr/bin/perl
use warnings;
use strict;

my @input_file = split /\n/, <<'__EOF__';
abc\**def\ghi**\abc\!!!!!
abc\**4nfiug\frgrefd\gtefe\wf4fs**\abc\df3gwddw
abc\**eg4/refw**\abc\f3
__EOF__

my $pattern = qr/abc\\.*\\abc/;       # pattern to be matched
my $string2 = join "\n", @input_file; # the string that need to be replaced
my $string3 = 'ABC\CBA';              # string i that i want it to replace to

$string2 =~ s/$pattern/$string3/g;
print $string2;

Upvotes: 1

Related Questions