How to append a file accordingly?

How to append a file accordingly?

am 26.11.2007 03:30:52 von Yaw Lim

How to append to a text file based on the following conditions:
1) if the last characters of the file are "\n" or "\r\n", simply
print FH "$some_text";
2) if the last characters are none of "\n" or "\r" or "\r\n", do
print FH "\n$some_text";

/Why Tea

Re: How to append a file accordingly?

am 26.11.2007 03:46:32 von Petr Vileta

Why Tea wrote:
> How to append to a text file based on the following conditions:
> 1) if the last characters of the file are "\n" or "\r\n", simply
> print FH "$some_text";
> 2) if the last characters are none of "\n" or "\r" or "\r\n", do
> print FH "\n$some_text";
>
> /Why Tea

Maybe this way?

if($some_text =~ m/(\r\n|\n|\r)$/s)
{
print FH "$some_text";
}
else
{
print FH "\n$some_text";
}

--
Petr
Skype: callto://fidokomik
Na mail uvedeny v headeru zpravy nema cenu nic posilat, konci to v PR*
:-)

Odpovidejte na petr na practisoft cz


Petr Vileta, Czech republic
(My server rejects all messages from Yahoo and Hotmail. Send me your
mail from another non-spammer site please.)

Please reply to

Re: How to append a file accordingly?

am 26.11.2007 06:26:39 von Yaw Lim

On Nov 26, 1:46 pm, "Petr Vileta" wrote:
> Why Tea wrote:
> > How to append to a text file based on the following conditions:
> > 1) if the last characters of the file are "\n" or "\r\n", simply
> > print FH "$some_text";
> > 2) if the last characters are none of "\n" or "\r" or "\r\n", do
> > print FH "\n$some_text";
>
> > /Why Tea
>
> Maybe this way?
>
> if($some_text =~ m/(\r\n|\n|\r)$/s)
> {
> print FH "$some_text";
> }
> else
> {
> print FH "\n$some_text";
> }
>

Petr, your code checks for white spaces at the end of $some_text, but
I was talking about white spaces at the end of the opened file, i.e.
open(FH, $some_file)

Re: How to append a file accordingly?

am 26.11.2007 11:01:25 von Spiros Denaxas

On Nov 26, 5:26 am, Why Tea wrote:
> On Nov 26, 1:46 pm, "Petr Vileta" wrote:
>
>
>
> > Why Tea wrote:
> > > How to append to a text file based on the following conditions:
> > > 1) if the last characters of the file are "\n" or "\r\n", simply
> > > print FH "$some_text";
> > > 2) if the last characters are none of "\n" or "\r" or "\r\n", do
> > > print FH "\n$some_text";
>
> > > /Why Tea
>
> > Maybe this way?
>
> > if($some_text =~ m/(\r\n|\n|\r)$/s)
> > {
> > print FH "$some_text";
> > }
> > else
> > {
> > print FH "\n$some_text";
> > }
>
> Petr, your code checks for white spaces at the end of $some_text, but
> I was talking about white spaces at the end of the opened file, i.e.
> open(FH, $some_file)

Why Tea,

I believe Petr's solution involves slurping the file and then
checking.
You could use:

File::Slurp http://search.cpan.org/perldoc?Perl6::Slurp
Perl6::Slurp http://search.cpan.org/perldoc?File::Slurp

How big is the file? I believe this is a crucial factor since
for very long and/or large files, the majority of common methods
might not be applicable.

Spiros

Re: How to append a file accordingly?

am 26.11.2007 11:20:36 von Peter Makholm

Why Tea writes:

> How to append to a text file based on the following conditions:
> 1) if the last characters of the file are "\n" or "\r\n", simply
> print FH "$some_text";
> 2) if the last characters are none of "\n" or "\r" or "\r\n", do
> print FH "\n$some_text";

Untested and without error handling:

use Fcntl qw(:seek);

my $last;
open my $fh, '+<', $filename;
seek $fh, -1, SEEK_END;
read $fh, $last, 1;
seek $fh, 0, SEEK_END; # Probably not needed.

print {$fh} "\n" unless $last eq "\n";
print {$fh} $some_text;

Re: How to append a file accordingly?

am 26.11.2007 13:30:57 von Tad McClellan

Petr Vileta wrote:

> if($some_text =~ m/(\r\n|\n|\r)$/s)
^
^

the m//s modifier is a no-op for that regex.

You should not use modifiers that do not do any modification...


--
Tad McClellan
email: perl -le "print scalar reverse qq/moc.noitatibaher\100cmdat/"

Re: How to append a file accordingly?

am 26.11.2007 15:07:27 von Abigail

_
Tad McClellan (tadmc@seesig.invalid) wrote on VCC September MCMXCIII in
:
:) Petr Vileta wrote:
:)
:) > if($some_text =~ m/(\r\n|\n|\r)$/s)
:) ^
:) the m//s modifier is a no-op for that regex.
:)
:) You should not use modifiers that do not do any modification...


Hmmmpf.


Although I don't necessarely disagree with you, I don't think such
posts are useful. What might be useful is a reasoning why you think
you shouldn't do so. Preferably also with reasons why people (Damian
for instance, in PBP) do think you should.

I seldomly use /s, /m or /x when it's not needed, but I won't held it
against people that do.


And, given that 5.10 is just around the corner, I'd write the code as:

if ($some_text =~ /\R$/)


Abigail
--
package Just_another_Perl_Hacker; sub print {($_=$_[0])=~ s/_/ /g;
print } sub __PACKAGE__ { &
print ( __PACKAGE__)} &
__PACKAGE__
( )

Re: How to append a file accordingly?

am 26.11.2007 17:41:45 von Petr Vileta

Why Tea wrote:
> On Nov 26, 1:46 pm, "Petr Vileta" wrote:
>>
>> Maybe this way?
>>
>> if($some_text =~ m/(\r\n|\n|\r)$/s)
>> {
>> print FH "$some_text";
>> }
>> else
>> {
>> print FH "\n$some_text";
>> }
>>
>
> Petr, your code checks for white spaces at the end of $some_text, but
> I was talking about white spaces at the end of the opened file, i.e.
> open(FH, $some_file)

I assumed that whole file content is in $some_text. When you can read file
line by line then you can use this

open FH "< $myfile";
binmode FH; # not need for *nix systems
seek FH, -2, 2; # seek for last 2 bytes
my $lastchars = ;
close FH;
open FH "< $myfile";
while (my $row = )
{
print $row;
}
close FH;
print "\n" unless($lastchars =~ m/(\r\n|\n|\r)$/s)
--
Petr
Skype: callto://fidokomik
Na mail uvedeny v headeru zpravy nema cenu nic posilat, konci to v PR*
:-)

Odpovidejte na petr na practisoft cz


Petr Vileta, Czech republic
(My server rejects all messages from Yahoo and Hotmail. Send me your
mail from another non-spammer site please.)

Please reply to

Re: How to append a file accordingly?

am 26.11.2007 23:24:56 von Yaw Lim

On Nov 27, 3:41 am, "Petr Vileta" wrote:
> Why Tea wrote:
> > On Nov 26, 1:46 pm, "Petr Vileta" wrote:
>
> >> Maybe this way?
>
> >> if($some_text =~ m/(\r\n|\n|\r)$/s)
> >> {
> >> print FH "$some_text";
> >> }
> >> else
> >> {
> >> print FH "\n$some_text";
> >> }
>
> > Petr, your code checks for white spaces at the end of $some_text, but
> > I was talking about white spaces at the end of the opened file, i.e.
> > open(FH, $some_file)
>
> I assumed that whole file content is in $some_text. When you can read file
> line by line then you can use this
>
> open FH "< $myfile";
> binmode FH; # not need for *nix systems
> seek FH, -2, 2; # seek for last 2 bytes
> my $lastchars = ;
> close FH;
> open FH "< $myfile";
> while (my $row = )
> {
> print $row;
> }
> close FH;
> print "\n" unless($lastchars =~ m/(\r\n|\n|\r)$/s)
> --

Thanks Petr. The code works fine in detecting \r\n|\n|\r, but it fails
when the $lastchars are just normal characters. What I did was to
append a line of text to the file and I didn't want to have a blank
line if there is already \r\n|\n|\r. I ran your code once, it was OK
but the subsequent runs failed (I expected \n to be printed, but it
didn't).

/Why Tea

Re: How to append a file accordingly?

am 27.11.2007 00:47:19 von Ben Morrow

Quoth Why Tea :
> On Nov 27, 3:41 am, "Petr Vileta" wrote:
> >
> > open FH "< $myfile";

Use three-arg open.
Use lexical filehandles.
Check the open succeeded.

> > binmode FH; # not need for *nix systems

Yes, it is *always* needed as of 5.8. You can also combine this step
with the open:

open my $FH, '<:raw', $myfile
or die "can't read '$myfile': $!";

> > seek FH, -2, 2; # seek for last 2 bytes

Don't use magic numbers for seek. Use the proper constants: it's
clearer, and safer if you ever port the code to a machine where SEEK_END
isn't 2 (such things do happen: GNU Hurd, for instance, has O_RDONLY
defined as 1 rather than 0).

use Fcntl qw/:seek/;

seek $FH, -2, SEEK_END;

> > my $lastchars = ;
> > close FH;
> > open FH "< $myfile";

Why do this? It just introduces an entirely unnecessary race condition,
and you haven't reopened it in binary mode, which may or may not be
important. If you wish to reinstate CRLF processing, you can say

binmode $FH, ':crlf';

> > while (my $row = )
> > {
> > print $row;
> > }
> > close FH;

It's not clear the OP wants to copy the file. If he wants to append, it
would be better to open in '+<' mode seek to the end before writing.

> > print "\n" unless($lastchars =~ m/(\r\n|\n|\r)$/s)

While I'm usually a fan of using regexes rather than more low-level
solutions, this is more complicated than necessary. Something like

seek $FH, -1, SEEK_END;
or die "can't seek '$myfile': $!";
read $FH, my $eol, 1
or die "can't read from '$myfile': $!";

seek $FH, 0, SEEK_END;
print $FH "\n" unless $eol =~ tr/\r\n//;

would be simpler. If you want to insert a newline matching the rest of
the file, you would need to read at least two characters, of course. For
normalizing newlines see PerlIO::eol.

Note also that "\r" and "\n" are not portable. Some systems have "\r" eq
"\012" and "\n" eq "\015". If you mean an ASCII CR say "\015".

> Thanks Petr. The code works fine in detecting \r\n|\n|\r, but it fails
> when the $lastchars are just normal characters. What I did was to
> append a line of text to the file and I didn't want to have a blank
> line if there is already \r\n|\n|\r. I ran your code once, it was OK
> but the subsequent runs failed (I expected \n to be printed, but it
> didn't).

It works for me here. Please post a complete script that shows how it
fails.

Note that text files *should* end with a trailing newline (in the
appropriate local format). If you have files that don't, they're
arguably broken, and you're better off fixing them than propagating the
error.

Ben

Re: How to append a file accordingly?

am 27.11.2007 01:05:34 von Tad McClellan

Abigail wrote:
> _
> Tad McClellan (tadmc@seesig.invalid) wrote on VCC September MCMXCIII in
>:
>:) Petr Vileta wrote:
>:)
>:) > if($some_text =~ m/(\r\n|\n|\r)$/s)
>:) ^
>:) the m//s modifier is a no-op for that regex.
>:)
>:) You should not use modifiers that do not do any modification...
>
>
> Hmmmpf.
>
>
> Although I don't necessarely disagree with you, I don't think such
> posts are useful. What might be useful is a reasoning why you think
> you shouldn't do so.


My folks often told me "look both ways before you cross the street"
without explaining why I should.


A modifier says "something out of the ordinary is going on here".

Modifiers that don't modify are "crying wolf" to the maintenance programmer.


> Preferably also with reasons why people (Damian
> for instance, in PBP) do think you should.


I don't really remember why he said to use m//msx, but I think it was
"because they will be enabled by default in Perl 6", ie. to get
yourself ready for Perl 6.

I'll learn Perl 6 when there _is_ a Perl 6 , but while maintaining
Perl 5 code, I'm not going to cry wolf.

(I only have "buy in" for about 80% of the PBP recommendations anyway.)


--
Tad McClellan
email: perl -le "print scalar reverse qq/moc.noitatibaher\100cmdat/"

Re: How to append a file accordingly?

am 27.11.2007 02:00:56 von Yaw Lim

> It works for me here. Please post a complete script that shows how it
> fails.
>

Sorry, I made a mistake. Petr's code actually works. And your code
works fine too, Ben.

Another question, how do you extract the last line of a text file
quickly?

/Why Tea

Re: How to append a file accordingly?

am 27.11.2007 03:05:05 von Jim Gibson

In article
,
Why Tea wrote:

> > It works for me here. Please post a complete script that shows how it
> > fails.
> >
>
> Sorry, I made a mistake. Petr's code actually works. And your code
> works fine too, Ben.
>
> Another question, how do you extract the last line of a text file
> quickly?

Check out File::ReadBackwards:



--
Jim Gibson

Posted Via Usenet.com Premium Usenet Newsgroup Services
----------------------------------------------------------
** SPEED ** RETENTION ** COMPLETION ** ANONYMITY **
----------------------------------------------------------
http://www.usenet.com

Re: How to append a file accordingly?

am 27.11.2007 06:27:53 von xhoster

Tad McClellan wrote:
> Abigail wrote:
> > _
> > Tad McClellan (tadmc@seesig.invalid) wrote on VCC September MCMXCIII in
> >:
> >:) Petr Vileta wrote:
> >:)
> >:) > if($some_text =~ m/(\r\n|\n|\r)$/s)
> >:) ^
> >:) the m//s modifier is a no-op for that regex.
> >:)
> >:) You should not use modifiers that do not do any modification...
> >
> >
> > Hmmmpf.
> >
> >
> > Although I don't necessarely disagree with you, I don't think such
> > posts are useful. What might be useful is a reasoning why you think
> > you shouldn't do so.
>
> My folks often told me "look both ways before you cross the street"
> without explaining why I should.
>
> A modifier says "something out of the ordinary is going on here".
>
> Modifiers that don't modify are "crying wolf" to the maintenance
> programmer.

On the other hand, you could argue that /sm *is* ordinary, and their
removal is the mark of the unusual. If that is the standard to which the
maintenance programmer is accustomed, than their unwarranted absence would
be what is calling wolf, not their unwarranted presence. Sure, it would
have been nice if Perl had inverted their meanings in the first place, so
that the usual would be shorter than the unusual, but should we be
prisoners to a design flaw when we can just learn a new custom instead?

Xho

--
-------------------- http://NewsReader.Com/ --------------------
The costs of publication of this article were defrayed in part by the
payment of page charges. This article must therefore be hereby marked
advertisement in accordance with 18 U.S.C. Section 1734 solely to indicate
this fact.

Re: How to append a file accordingly?

am 27.11.2007 07:09:46 von Petr Vileta

Ben Morrow wrote:
> Quoth Why Tea :
>> On Nov 27, 3:41 am, "Petr Vileta" wrote:
>>>
>>> open FH "< $myfile";
>
> Use three-arg open.
> Use lexical filehandles.
> Check the open succeeded.
>
>>> binmode FH; # not need for *nix systems
>
> Yes, it is *always* needed as of 5.8. You can also combine this step
> with the open:
>
Maybe you are right, I don't know. I'm old-fashioned, I still write scripts
for (and using) Perl 5.6.1 :-)
--
Petr Vileta, Czech republic
(My server rejects all messages from Yahoo and Hotmail. Send me your
mail from another non-spammer site please.)

Please reply to

Re: How to append a file accordingly?

am 27.11.2007 08:39:28 von Abigail

_
Tad McClellan (tadmc@seesig.invalid) wrote on VCCI September MCMXCIII in
:
:) Abigail wrote:
:) > _
:) > Tad McClellan (tadmc@seesig.invalid) wrote on VCC September MCMXCIII in
:) >:
:) >:) Petr Vileta wrote:
:) >:)
:) >:) > if($some_text =~ m/(\r\n|\n|\r)$/s)
:) >:) ^
:) >:) the m//s modifier is a no-op for that regex.
:) >:)
:) >:) You should not use modifiers that do not do any modification...
:) >
:) >
:) > Hmmmpf.
:) >
:) >
:) > Although I don't necessarely disagree with you, I don't think such
:) > posts are useful. What might be useful is a reasoning why you think
:) > you shouldn't do so.
:)
:)
:) My folks often told me "look both ways before you cross the street"
:) without explaining why I should.
:)
:)
:) A modifier says "something out of the ordinary is going on here".
:)
:) Modifiers that don't modify are "crying wolf" to the maintenance programmer.
:)
:)
:) > Preferably also with reasons why people (Damian
:) > for instance, in PBP) do think you should.
:)
:)
:) I don't really remember why he said to use m//msx, but I think it was
:) "because they will be enabled by default in Perl 6", ie. to get
:) yourself ready for Perl 6.

No, that's not the reason. They are by default enabled in Perl6 because
the people developing Perl6 think it's a good idea to have them enabled
by default (and no way to easily turn them off). And for the same reasons
they are on in Perl6, Damian advocates to use them - and to make it easier
for the maintainance programmer, he advocates to turn them always on (that
way, when you see an unescaped '.', '^', '$', '#' or ' ' in a regexp, it
always means the same thing).

I don't buy your argument, and I don't by Damians either. Anyone who
considers /s or /m to be an alarm, or loses track when sometimes /s is
used, and sometimes isn't, shouldn't program Perl in the first place.



Abigail
--
perl -wle 'sub _ "Just another Perl Hacker"; print prototype q ^_^'

Re: How to append a file accordingly?

am 27.11.2007 12:14:45 von sheinrich

On Nov 27, 8:39 am, Abigail wrote:
....
>
> No, that's not the reason. They are by default enabled in Perl6 because
> the people developing Perl6 think it's a good idea to have them enabled
> by default (and no way to easily turn them off). And for the same reasons
> they are on in Perl6, Damian advocates to use them - and to make it easier
> for the maintainance programmer, he advocates to turn them always on (that
> way, when you see an unescaped '.', '^', '$', '#' or ' ' in a regexp, it
> always means the same thing).
>
> I don't buy your argument, and I don't by Damians either. Anyone who
> considers /s or /m to be an alarm, or loses track when sometimes /s is
> used, and sometimes isn't, shouldn't program Perl in the first place.
>
> Abigail
> --
While I share your point of view on the usage of modifiers, I'm afraid
that the outspoken 'perl-enabled' folk's snobbish attitude might be
cause for people feeling rebuffed and for the language's slowly ebbing
popularity.

TIMTOWTDI

Cheers,
Steffen