repacing the last line in a file

V

Vahid

Hi,
With the following code, I can search and replace a pattern in a file,
but I am not too sure if that is a correct way or if there is a better
solution.
I will *only* look for the "." dot which is *always* at the last
line in a file and replace it with a string and add the dot at the end
of the file again.

while (<INPUT_Handle>)
{
$INP_LINE=$_;
$INP_LINE=~ s/$ORIG_string/$NEW_string/g;
print OUTPUT_Handle "$INP_LINE";
};
close(INPUT_Handle);
close(OUTPUT_Handle);
};
Thanks for the help.
Vahid.
 
P

Paul Lalli

Vahid said:
With the following code, I can search and replace a pattern in a file,
but I am not too sure if that is a correct way or if there is a better
solution.
I will *only* look for the "." dot which is *always* at the last
line in a file and replace it with a string and add the dot at the end
of the file again.

while (<INPUT_Handle>)
{
$INP_LINE=$_;

This is more commonly written:

while (my $INP_LINE = said:
$INP_LINE=~ s/$ORIG_string/$NEW_string/g;

If I understand you correctly, $ORIG_string contains '.', and
$NEW_string contains some text followed by a ".\n". Is that true?

If so, you need to escape $ORIG_string, as the period is a special
character.
$INP_LINE =~ s/\Q$ORIG_string\E/$NEW_string/g;
print OUTPUT_Handle "$INP_LINE";

Please read:
perldoc -q quoting
"What's wrong with always quoting "$vars"? "
};
close(INPUT_Handle);
close(OUTPUT_Handle);
};

Some alternative approaches you might want to consider (both untested):

1) Tie the file to an array, and just insert your line right before the
end:
use Tie::File;
tie my @file, 'Tie::File', 'file.txt' or die $!;
splice @file, -1, 0, $NEW_string;

2) loop through the file, constantly checking to see if you're on the
last line by determining whether or not the next read will give an end
of file. If so, print your new line before printing the current line.

while (my $INP_LINE = <INPUT_Handle>){
print OUTPUT_Handle $NEW_string if eof;
print OUTPUT_Handle $INP_LINE;
}


For more information:
http://search.cpan.org/~mjd/Tie-File-0.96/lib/Tie/File.pm
perldoc -f splice
perldoc -f eof

Paul Lalli
 
V

Vahid

Paul said:
This is more commonly written:

while (my $INP_LINE = <INPUT_Handle>) { Thanks.

If I understand you correctly, $ORIG_string contains '.', and
$NEW_string contains some text followed by a ".\n". Is that true?
Yes, I will parse the file until the last line where the dot "." is,
and replace it with the new string and add the dot to the last line in
the file.
string1
string2
string3
..
If so, you need to escape $ORIG_string, as the period is a special
character.
$INP_LINE =~ s/\Q$ORIG_string\E/$NEW_string/g;


Please read:
perldoc -q quoting just did, thanks.

Some alternative approaches you might want to consider (both untested):

1) Tie the file to an array, and just insert your line right before the
end:
use Tie::File;
tie my @file, 'Tie::File', 'file.txt' or die $!;
splice @file, -1, 0, $NEW_string;
this looks good, I think I will use this.
2) loop through the file, constantly checking to see if you're on the
last line by determining whether or not the next read will give an end
of file. If so, print your new line before printing the current line.

while (my $INP_LINE = <INPUT_Handle>){
print OUTPUT_Handle $NEW_string if eof;
print OUTPUT_Handle $INP_LINE;
}


For more information:
http://search.cpan.org/~mjd/Tie-File-0.96/lib/Tie/File.pm
perldoc -f splice
perldoc -f eof
Thanks Paul.
 
T

Tad McClellan

Vahid said:
I will *only* look for the "." dot which is *always* at the last
line in a file and replace it with a string and add the dot at the end
of the file again.


perldoc -q file

How do I change one line in a file/delete a line in a file/insert a
line in the middle of a file/append to the beginning of a file?

while (<INPUT_Handle>)
{
$INP_LINE=$_;


If you want it in $INP_LINE, then put it into $INP_LINE
in the first place:

while ( $INP_LINE = <INPUT_Handle> )

(whitespace is not a scarce resource. Feel free to use as much of
it as you like to make your code easier to read and understand.
)

print OUTPUT_Handle "$INP_LINE";


perldoc -q vars
 
A

Anno Siegel

Paul Lalli said:
Vahid said:
With the following code, I can search and replace a pattern in a file,
but I am not too sure if that is a correct way or if there is a better
solution.
I will *only* look for the "." dot which is *always* at the last
line in a file and replace it with a string and add the dot at the end
of the file again.
[...]

1) Tie the file to an array, and just insert your line right before the
end:
use Tie::File;
tie my @file, 'Tie::File', 'file.txt' or die $!;
splice @file, -1, 0, $NEW_string;

That fails to move the final dot around as required. Also, why splice()
when push() would do?

chop @file[ -1] eq '.' or die "Data error";
push @file, "$NEW_string.";

Anno
 
P

Paul Lalli

Anno said:
Paul Lalli said:
Vahid said:
With the following code, I can search and replace a pattern in a file,
but I am not too sure if that is a correct way or if there is a better
solution.
I will *only* look for the "." dot which is *always* at the last
line in a file and replace it with a string and add the dot at the end
of the file again.
[...]

1) Tie the file to an array, and just insert your line right before the
end:
use Tie::File;
tie my @file, 'Tie::File', 'file.txt' or die $!;
splice @file, -1, 0, $NEW_string;

That fails to move the final dot around as required. Also, why splice()
when push() would do?

chop @file[ -1] eq '.' or die "Data error";
push @file, "$NEW_string.";

I was under the impression the OP wanted to add a line to the file,
just before the line with the period, not that the user wanted to
insert additional text before the period on the last line of the file.

I could have been wrong.

Paul Lalli
 
A

Anno Siegel

Paul Lalli said:
Anno said:
Paul Lalli said:
Vahid wrote:
With the following code, I can search and replace a pattern in a file,
but I am not too sure if that is a correct way or if there is a better
solution.
I will *only* look for the "." dot which is *always* at the last
line in a file and replace it with a string and add the dot at the end
of the file again.
[...]

1) Tie the file to an array, and just insert your line right before the
end:
use Tie::File;
tie my @file, 'Tie::File', 'file.txt' or die $!;
splice @file, -1, 0, $NEW_string;

That fails to move the final dot around as required. Also, why splice()
when push() would do?

chop @file[ -1] eq '.' or die "Data error";
push @file, "$NEW_string.";

I was under the impression the OP wanted to add a line to the file,
just before the line with the period, not that the user wanted to
insert additional text before the period on the last line of the file.

Looking back I see the question was indeed less clear than I thought,
though I'm still reading it the way I did. Never mind...

Anno
 
V

Vahid Moghaddasi

Paul said:
That fails to move the final dot around as required. Also, why splice()
when push() would do?

chop @file[ -1] eq '.' or die "Data error";
push @file, "$NEW_string.";

I was under the impression the OP wanted to add a line to the file,
just before the line with the period, not that the user wanted to
insert additional text before the period on the last line of the file.

I could have been wrong.
Paul, you assumed correctly, the last line in the file *must* always be
a single dot. Each additional text must be before the dot not with the
dot, e.g.
text1
test2
..
I am trying to add new user alias assignment in qmail MTA if you want
to know.
so far I tried,
while ($INP_LINE = <ASSIGN>) {
print ASSIGN_OUT $assign if eof;
print ASSIGN_OUT $INP_LINE;
but the period is joined with the last line. I need to insert CR just
before the dot.
 
P

Paul Lalli

Vahid said:
Paul, you assumed correctly, the last line in the file *must* always be
a single dot. Each additional text must be before the dot not with the
dot, e.g.
text1
test2
.
I am trying to add new user alias assignment in qmail MTA if you want
to know.
so far I tried,
while ($INP_LINE = <ASSIGN>) {
print ASSIGN_OUT $assign if eof;
print ASSIGN_OUT $INP_LINE;
but the period is joined with the last line. I need to insert CR just
before the dot.

What is $assign? Does $assign have a newline on the end? Perl won't
just print out a newline without you telling it to.

Either recode $assign to automatically have a newline, or print the
newline separately:

print ASSIGN_OUT "$assign\n" if eof;

Paul Lalli
 
V

Vahid Moghaddasi

Paul said:
print ASSIGN_OUT "$assign\n" if eof;
Thanks, "$assign\n" works. I already had a "\n" in $assign but was not
working for me, here is $assign:
$assign="=$new_user:$new_user:$new_uid:$new_gid:$def_qmail/alias:-:$new_user\n";
in fact \n in $assign has no affect so I took it out.
Thanks again.
 
P

Paul Lalli

Vahid said:
Thanks, "$assign\n" works. I already had a "\n" in $assign but was not
working for me, here is $assign:
$assign="=$new_user:$new_user:$new_uid:$new_gid:$def_qmail/alias:-:$new_user\n";
in fact \n in $assign has no affect so I took it out.

I find that exceedingly unlikely. Perl is not simply going to ignore a
\n character.

Are you sure you weren't accidentally chomping the variable before
printing it?
Thanks again.

You're welcome.

Paul Lalli
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,774
Messages
2,569,596
Members
45,143
Latest member
SterlingLa
Top