Perl String Replacement Syntax Question . . .


 
Thread Tools Search this Thread
Top Forums Shell Programming and Scripting Perl String Replacement Syntax Question . . .
# 1  
Old 05-17-2014
Perl String Replacement Syntax Question . . .

Greetings!

I've been tooling about with Perl to make a few string replacements in some files; and seem to have run into a bit of a squeeze Smilie

Beginning with a simple text file, test.txt, we have the following content to be worked:
Quote:
Mary had a little lamb.
Now, not wanting to have anyone feel left out, I decided that it would be nice if Joe could have his time in the sun as well. So, I invoked Perl from the commandline with the following generally-familiar "one liner":
Code:
perl -p -i -e 's/Mary/Joe/' test.txt

Works like a charm: Quick and easy; and Joe's happy, too Smilie

Now, being a curious sort of fellow, I decided to "simply" create a script which'd do the same thing as the above command; leading to the following "best effort" with my limited knowledge of the topic:
Code:
#!/usr/bin/perl -w
use strict;
use warnings;

my $file = 'test.txt';
open my $content, ">", $file or die("Could not open file. $!");

$content =~ s/Mary/Joe/g;

print $content $file;
close $content;

Input text: "Mary had a little lamb."
Output: "test.txt"

I know there's a simple twist I'm missing here; but can't get a grip on it for the life of me Smilie

Now, if I want to be really square, I can simply do a bash script with the single line,
Code:
perl -p -i -e 's/Mary/Joe/' test.txt

...and, of course, all works a treat without a fuss.

Incidentally, I will need to do a find/replace operation with whatever snippet finally emerges on several files at a time. I can get this to work as:
Code:
perl -p -i -e 's/Mary/Joe/' test.txt test2.txt test3.txt

...but haven't a single clue as to how this would translate over to an actual script in Perl.

Any hints/tips to get my humble codebit going in the right direction???


Thanks!
# 2  
Old 05-17-2014
You are truncating $file to writing.
Quote:
open my $content, ">", $file
Code:
#!/usr/bin/perl
# -w removed from shebag since it does the same that use warnings

use strict;
use warnings;

my $file = 'test.txt';
open (my $content, "<", $file) or die("Could not open file. $!");

# read the content one line at a time
while ( $line = <$content> ) {
    $line =~ s/Mary/Joe/g;
    print "$line";
}

close $content;


Last edited by Aia; 05-17-2014 at 06:43 PM.. Reason: spell correction
# 3  
Old 05-18-2014
@Aia: Thanks for stopping by.

However, the code didn't run out of the box.

Fixed:
Code:
#!/usr/bin/perl
# -w removed from shebag since it does the same that use warnings

use strict;
use warnings;
my $line;
my $file = 'test.txt';
open (my $content, "<", $file) or die("Could not open file. $!");

# read the content one line at a time
while ( $line = <$content> ) {
    $line =~ s/Mary/Joe/g;
    print "$line";
}

close $content;

While this ran, test.txt was unchanged; and the altered text was simply directed to the command line. Couldn't get any modification to work as planned...

So, after more digging around, I tried to rectify the problem thusly:
Code:
#!/usr/bin/perl

use diagnostics;
use strict;
use warnings;

our $content;

open ($content, "<", "test.txt");
$content =~ s/Mary/Joe/g;
open ($content, ">", "test.txt");

close $content;

This block runs without warnings or errors, but instead of the text ($content) being altered and returned to the original file (as the apparent logic/flow would indicate), all in "test.txt" is erased; and the script simply exits.

FWIW, the perldocs were rather confusing/obtuse on all of this...

???


Thanks again Smilie

---------- Post updated at 04:20 PM ---------- Previous update was at 04:05 PM ----------

Stop the presses!

Working with something over here. Seems I got confused over handles/content.

Back soon --

---------- Post updated at 04:39 PM ---------- Previous update was at 04:20 PM ----------

Back again.

This time, the code seems better in some regards, but the result is still the same: All content of test.txt is simply erased--
Code:
#!/usr/bin/perl

use diagnostics;
use warnings;
use strict;
 
my $src = 'test.txt';
my $des = 'test.txt';
my $line;
 
# open source file for reading
open(SRC,'<',$src) or die $!;
 
# open destination file for writing
open(DES,'>',$des) or die $!;
 
while($line = <SRC>){
$line =~ s/Mary/Joe/g;
   print $line $des;    
}
 
# always close the filehandles
close(SRC);
close(DES);

Really confused now...

Smilie
# 4  
Old 05-18-2014
Normally you open a file for reading and another for writing. After everything is modified you can delete the original and rename the temp file.

Code:
#!/usr/bin/perl

use strict;
use warnings;


open my $content_in, '<', "test.txt" or die("Could not open file. $!");
open my $content_out, '>', "test.tmp.txt" or die("Could not open file. $!");

while ( my $line = <$content_in> ) {
    $line =~ s/Mary/Joe/g;
    print $content_out $line;
}
close $content_in;
close $content_out;

unlink "test.txt";
rename "test.tmp.txt", "test.txt";

However, perl has many shortcuts and features of its own, like the in-place editing.

This will edit the original after making a backup file named .bak

Code:
#!/usr/bin/perl

use strict;
use warnings;

my $sources = 'test.txt';

@ARGV = ($sources);
$^I = '.bak';

while (<>) {
    s/Mary/Joe/g;
    print;
}

---------- Post updated at 03:13 PM ---------- Previous update was at 03:07 PM ----------

Quote:
print $line $des;
Reverse the scalarsprint $des $line
file handle first.
This User Gave Thanks to Aia For This Post:
# 5  
Old 05-19-2014
@Aia:

Awesome. Seems this is what I was looking for--
Code:
#!/usr/bin/perl

use diagnostics;
use warnings;
use strict;
 
@ARGV = ('test.txt', 'test2.txt');

$^I = '.bak';

while (<>) {
    s/Mary/Joe/g;
    print;
}

Smilie

Now, just one more question from the noob: Is this "properly formed" Perl? Also, can one invoke $^I like this:
Code:
$^I = '';

to avoid creating an intermediate temp file on the disk (could be useful when doing replacements on largish files)???

Finally, if you have just one more moment to spare along the way, what's the rule for quoting "string" and 'string' in a context such as this:
Code:
@ARGV = ("test.txt", 'test2.txt');

Both single and double quotes seem to work interchangeably without error or warning: Is the code agnostic when it comes to such conventions???

Thanks again!

Last edited by LinQ; 05-19-2014 at 02:04 PM.. Reason: Couple more thoughts ;)
# 6  
Old 05-19-2014
Code:
$^I = '';

Yes, that's the equivalent to just -i at the command line.

Quote:
Finally, if you have just one more moment to spare along the way, what's the rule for quoting "string" and 'string' in a context such as this:
Code:

@ARGV = ("test.txt", 'test2.txt');


Both single and double quotes seem to work interchangeably without error or warning: Is the code agnostic when it comes to such conventions???
You live or die by quotes in perl. There are even quote operators like q//, qq//
Any string surrounded by double quote allows interpolation or interpretation, like resolving the variable and scape symbols: e.g. $line, \n
Single quote do not interpolate variables or interpret especial characters, they are taken at face value.

In your example it does not make a difference.
This User Gave Thanks to Aia For This Post:
# 7  
Old 05-19-2014
@Aia:

Tucked away a lot here --

Thanks again for all the help; and have a great week Smilie
Login or Register to Ask a Question

Previous Thread | Next Thread

10 More Discussions You Might Find Interesting

1. Shell Programming and Scripting

A Perl Syntax Question.

Greetings! Here's what I believe is a "simple one" for the community tonight ;) What I'm trying to do is assign a "true/false" value to a variable depending upon whether a named process (some-process) exists; and then test for this value in the succeeding logic. I banged my head against the... (2 Replies)
Discussion started by: LinQ
2 Replies

2. Shell Programming and Scripting

String replacement

Hi, I have a text file where all records come in one line (single line file), each record starts with 'BUCH' and ends with '@&' and if data is not there we get space instead. between '@&' and next record there might be some spaces, now I want to remove those spaces between '@&' and 'BUCH'. ... (4 Replies)
Discussion started by: maks475
4 Replies

3. Programming

Perl syntax question

Hallo everybody, I have a following problem - I'm doing a map funciont to fill in a HTML table and I want to use some radiobutton groups. Unfortunatelly, they are grouped by names, so I have to add some "counter" that will divide one row from another, and I'm using CGI.pm for generating the... (3 Replies)
Discussion started by: duskos
3 Replies

4. Shell Programming and Scripting

String replacement.

Dear Friends, I want to replace following line with given line. It should grep/search following string in a file (input.txt) M/M SRNO: 000M/6200-0362498 COSMETIC PRO MALE FEMALE Once found it should replace it to following string. T_DLHNNO: 000M/6200-0362498 ... (7 Replies)
Discussion started by: anushree.a
7 Replies

5. UNIX for Dummies Questions & Answers

sed string replacement question

Hey everybody. I've got a simple problem but am unsure how to resolve it. I am using a script to edit multiple files at once. Inside the script I am using an sed command to make the changes. My problem is that I can only get it to work for stings that contain a word or words. How can I modify it to... (1 Reply)
Discussion started by: iwatk003
1 Replies

6. Shell Programming and Scripting

String replacement

Hi All, I have below file which has data in below format. #$ | AB_100 | AB_300 ()| AB_4 @*(% | AB-789 i want o/p as below format. | AB_100 | AB_300 | AB_4 | AB-789 So here there is no standard format. How we can achieve the same in unix ? Regards, (3 Replies)
Discussion started by: gander_ss
3 Replies

7. Shell Programming and Scripting

String replacement

I have one string string1=user/password:IP_ADDR:Directory I need to replace string1 value like store into string2 string2=user password:IP_ADDR:Directory i.e replace "/" character by '<space>' character But i wouldn't use any file in the meantime. Please help me......................... (6 Replies)
Discussion started by: mnmonu
6 Replies

8. Shell Programming and Scripting

perl: simple question on string append

I want to append a decimal number to a string. But I want to restrict the number to only 2 decimal points for e.g: my $output = "\n The number is = "; my $number = 2.3333333; $output = $output . $number; But I want the $output as: "The number is = 2.33"; and not 2.3333333 (I do not... (1 Reply)
Discussion started by: the_learner
1 Replies

9. Shell Programming and Scripting

String Replacement with Perl

I want to replace a string within a file using perl. We have a line that gets commented out, and I want to replace that line now matter how it was commented out. for example, I'd want to replace ###ES=PR1A with ES=PR1A or ##LJW(9/16/26)ES=PR1A with ES=PR1A I tried: perl... (4 Replies)
Discussion started by: Lindarella
4 Replies

10. Shell Programming and Scripting

sed problem - replacement string should be same length as matching string.

Hi guys, I hope you can help me with my problem. I have a text file that contains lines like this: 78 ANGELO -809.05 79 ANGELO2 -5,000.06 I need to find all occurences of amounts that are negative and replace them with x's 78 ANGELO xxxxxxx 79... (4 Replies)
Discussion started by: amangeles
4 Replies
Login or Register to Ask a Question