develooper Front page | perl.beginners | Postings from February 2009

Re: replace text in file

Thread Previous
From:
Jim Gibson
Date:
February 25, 2009 18:05
Subject:
Re: replace text in file
Message ID:
C5CB38FB.41FD%JimSGibson@gmail.com
On 2/25/09 Wed  Feb 25, 2009  5:02 PM, "lemba" <lemba@sbcglobal.net>
scribbled:

> Hi All,
> 
> I'm trying to replace some text in file. Below is my script. It
> basically makes a copy of line with changes. How can I replace pattern
> in the uxix sed way?

I don't use sed, but you can use Perl "one-liners" to emulate sed. See
'perldoc perlrun' and the -p, -I, and -e options. Example:

perl -p -i -e 's/(starbucks.*)restaurant/$1CAFE/i' file.txt

Although for more control, you might still want to write a full script. Even
in a full script, you can use the $^I variable to enable in-place editing
using the <> file input operator, if desired, emulating the -I command-line
option.

> 
> use strict;
> use warnings;
> use Cwd;
> use Win32;
> use File::Path;
> use File::Find;
> use File::Basename;
> 
> @ARGV = Win32::GetCwd() unless @ARGV;
> 
> my @source;
> find (\&findSource, $ARGV[0]);

You don't seem to be showing us your full script (findSource is missing). I
will assume that findSource puts file names to modify in the @source array.

> 
> foreach ( @source )
> {
>         open SOURCE, "+<", $_ or die "Error: $!\n";

You might want to add the file name ($_) to your error message.

         open SOURCE, "+<", $_ or die "Error in file $_: $!\n";

>         my @file = <SOURCE>;

@file is not a good variable name for an array that holds lines in a file. I
would suggest @lines might be better.

> 
>         seek SOURCE,0,0;
>        
>         foreach my $file (@file)

Maybe $line is a better name than $file here?

>         {
>                 if ( $file =~ /STARBUCKS.*RESTAURANT/i )
>                 {
>                    $file =~ s/RESTAURANT/CAFE/g;
>                    print SOURCE $file;

You want to print $file if it doesn't match, so move this print statement
below the if statement (but see below for a solution that doesn't involve an
if statement.)
 
>                 }
>         }

There is no need to first test if $file matches, then substitute if it does.
The s/// operator will not substitute unless there is a match. You just have
to save the data you are matching or use look-ahead, look-behind constructs.
I find it easier to save, as I can never remember the syntax for
look-arounds:

    $file =~ s/(STARBUCKS.*)RESTAURANT/$1CAFE/i;
    print SOURCE $file;


>         close SOURCE;
> }
> 
> Example of my original file:
> STARBUCKS|RESTAURANT
> JACK IN THE BOX|RESTAURANT
> STARBUCKS|RESTAURANT
> MC DONALDS|RESTAURANT
> 
> after replacement it should be like this:
> STARBUCKS|CAFE
> JACK IN THE BOX|RESTAURANT
> STARBUCKS|CAFE
> MC DONALDS|RESTAURANT
> 
> Thanks in advance,
> Vladimir
> 



Thread Previous


nntp.perl.org: Perl Programming lists via nntp and http.
Comments to Ask Bjørn Hansen at ask@perl.org | Group listing | About