For Programmers: Free Programming Magazines  


Home > Archive > PERL Beginners > July 2006 > Regex find and replace - delete line









You are viewing an archived Text-only version of the thread. To view this thread in it's original format and/or if you want to reply to this thread please [click here]

 

Author Regex find and replace - delete line
James Turnbull

2006-07-23, 3:57 am

-----BEGIN PGP SIGNED MESSAGE-----
Hash: RIPEMD160

Hi all

This feels like a really dumb question but doing a regex find and
replace is it possible to delete a line? For example,

for (@file) {
s/foo//g;
}

which equates to:

for each element in array 'file' if you find 'foo' then replace it with
null.

I then write the array to a file (using Tie::File) and it leaves a blank
line where the element containing 'foo' was like:

null
foo1
foo2
foo3

Perhaps I am confabulating two ideas here? Is there a way to walk
through an array and find a particular array element and delete it
rather than replace it with null (and then write it out to a file using
Tie::File)?

Thanks

James Turnbull

- --
James Turnbull <james@lovedthanlost.net>
- ---
Author of Pro Nagios 2.0
(http://www.amazon.com/gp/product/1590596099/)

Hardening Linux
(http://www.amazon.com/gp/product/1590594444/)
- ---
PGP Key (http://pgp.mit.edu:11371/pks/lookup...arch=0x0C42DF40)
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.3 (Darwin)

iD8DBQFEwxCt9hTGvAxC30ARA3AUAKDQeVzurdxg
3GMnwVlokIwk48Ed+ACghe0X
BJ+hUGw/QYUtQCSKU6+J8uk=
=Dmhk
-----END PGP SIGNATURE-----
D. Bolliger

2006-07-23, 7:57 am

James Turnbull am Sonntag, 23. Juli 2006 08:01:
> Hi all


Hi James

> This feels like a really dumb question but doing a regex find and
> replace is it possible to delete a line? For example,


The example below does not handle lines, but array entries (the entries may be
used as lines in the extended context, but they are just array entries for
the moment). The name '@file' may be a bit misleading.

> for (@file) {
> s/foo//g;
> }


This means: For every entry in the array, replace all occurances of the
string 'foo' with the empty string, for example
"My foo loves foos" => "My loves s"

> which equates to:
>
> for each element in array 'file' if you find 'foo' then replace it with
> null.
>
> I then write the array to a file (using Tie::File) and it leaves a blank
> line where the element containing 'foo' was like:
>
> null
> foo1
> foo2
> foo3
>
> Perhaps I am confabulating two ideas here? Is there a way to walk
> through an array and find a particular array element and delete it
> rather than replace it with null (and then write it out to a file using
> Tie::File)?


If you want to delete entries from @file completely...

a) that _equal_ to 'foo' (and the entry does not contain a line ending):

@file=grep { $_ eq 'foo' } @file;

b) that _contain_ one ore more 'foo' (presence of line ending does
not matter):

@file=grep { !/foo/ } @file;


Does this help?

Dani
Chad Perrin

2006-07-23, 7:57 am

On Sun, Jul 23, 2006 at 01:53:35PM +0200, D. Bolliger wrote:
>
> If you want to delete entries from @file completely...
>
> a) that _equal_ to 'foo' (and the entry does not contain a line ending):
>
> @file=grep { $_ eq 'foo' } @file;


If I'm missing something, I blame the fact that it's only six in the
morning, but . . .

.. . . shouldn't that be "ne" instead of "eq"?

--
CCD CopyWrite Chad Perrin [ http://ccd.apotheon.org ]
Brian K. Reid: "In computer science, we stand on each other's feet."
D. Bolliger

2006-07-23, 7:57 am

Chad Perrin am Sonntag, 23. Juli 2006 14:11:
> On Sun, Jul 23, 2006 at 01:53:35PM +0200, D. Bolliger wrote:
>
> If I'm missing something, I blame the fact that it's only six in the
> morning, but . . .
>
> . . . shouldn't that be "ne" instead of "eq"?


Yes, of course it should be "ne" . . .

.. . . we have 34 degrees here

Dani
John W. Krahn

2006-07-23, 6:56 pm

James Turnbull wrote:
> Hi all


Hello,

> This feels like a really dumb question but doing a regex find and
> replace is it possible to delete a line? For example,
>
> for (@file) {
> s/foo//g;
> }
>
> which equates to:
>
> for each element in array 'file' if you find 'foo' then replace it with
> null.
>
> I then write the array to a file (using Tie::File) and it leaves a blank
> line where the element containing 'foo' was like:
>
> null
> foo1
> foo2
> foo3
>
> Perhaps I am confabulating two ideas here? Is there a way to walk
> through an array and find a particular array element and delete it
> rather than replace it with null (and then write it out to a file using
> Tie::File)?


As you have seen when using Tie::File removing the contents of a line do not
remove that line. You have to splice the tied array:


my $line_to_remove;

for my $i ( 0 .. $#file ) {
$line_to_remove = $i if /foo/;
}

splice @file, $line_to_remove, 1;


If you have more than one line to remove:


my @lines_to_remove;

for my $i ( 0 .. $#file ) {
unshift @lines_to_remove, $i if /foo/;
}

for ( @lines_to_remove ) {
splice @file, $_, 1;
}


And if you want to do it with one loop:


for my $i ( reverse 0 .. $#file ) {
splice @file, $i, 1 if /foo/;
}



John
--
use Perl;
program
fulfillment
Rob Dixon

2006-07-24, 3:56 am

John W. Krahn wrote:
>
> As you have seen when using Tie::File removing the contents of a line do not
> remove that line. You have to splice the tied array:
>
> my $line_to_remove;
>
> for my $i ( 0 .. $#file ) {
> $line_to_remove = $i if /foo/;
> }
>
> splice @file, $line_to_remove, 1;
>
> If you have more than one line to remove:
>
> my @lines_to_remove;
>
> for my $i ( 0 .. $#file ) {
> unshift @lines_to_remove, $i if /foo/;
> }


for my $i ( 0 .. $#file ) {
unshift @lines_to_remove, $i if $file[$i] =~ /foo/;
}

OR

my $i = 0;
foreach ( @file ) {
unshift @lines_to_remove, $i if /foo/;
++$i;
}

> for ( @lines_to_remove ) {
> splice @file, $_, 1;
> }
>
>
> And if you want to do it with one loop:
>
>
> for my $i ( reverse 0 .. $#file ) {
> splice @file, $i, 1 if /foo/;
> }


Nice use of unshift() to avoid reverse(). Like it.

Rob
Randal L. Schwartz

2006-07-24, 3:56 am

>>>>> ""D" == "D Bolliger" <info@dbolliger.ch> writes:

"D> . . . we have 34 degrees here

34 degrees of what? How many radians is that?

--
Randal L. Schwartz - Stonehenge Consulting Services, Inc. - +1 503 777 0095
<merlyn@stonehenge.com> <URL:http://www.stonehenge.com/merlyn/>
Perl/Unix/security consulting, Technical writing, Comedy, etc. etc.
See PerlTraining.Stonehenge.com for onsite and open-enrollment Perl training!
Chris Charley

2006-07-24, 6:57 pm


----- Original Message -----
From: ""John W. Krahn"" <krahnj@telus.net>
Newsgroups: perl.beginners
To: "Perl Beginners" <beginners@perl.org>
Sent: Sunday, July 23, 2006 4:33 PM
Subject: Re: Regex find and replace - delete line


> James Turnbull wrote:
>
> Hello,
>
>
> As you have seen when using Tie::File removing the contents of a line do
> not
> remove that line. You have to splice the tied array:
>
>
> my $line_to_remove;
>
> for my $i ( 0 .. $#file ) {
> $line_to_remove = $i if /foo/;
> }
>
> splice @file, $line_to_remove, 1;
>
>
> If you have more than one line to remove:
>
>
> my @lines_to_remove;
>
> for my $i ( 0 .. $#file ) {
> unshift @lines_to_remove, $i if /foo/;
> }
>
> for ( @lines_to_remove ) {
> splice @file, $_, 1;
> }
>
>
> And if you want to do it with one loop:
>
>
> for my $i ( reverse 0 .. $#file ) {
> splice @file, $i, 1 if /foo/;
> }


Hi John

Shouldn't the above read like:

for my $i ( reverse 0 .. $#file ) {
splice @file, $i, 1 if $file[$i] =~ /foo/;

Chris

>
>
>
> John
> --
> use Perl;
> program
> fulfillment



John W. Krahn

2006-07-24, 6:57 pm

Chris Charley wrote:
>
> ----- Original Message ----- From: ""John W. Krahn"" <krahnj@telus.net>
>
> Hi John
>
> Shouldn't the above read like:
>
> for my $i ( reverse 0 .. $#file ) {
> splice @file, $i, 1 if $file[$i] =~ /foo/;


Yes it should, sorry about that mistake.



John
--
use Perl;
program
fulfillment
Derek Smith

2006-07-24, 6:57 pm


-----Original Message-----
From: John W. Krahn [mailto:krahnj@telus.net]=20
Sent: Monday, July 24, 2006 3:36 PM
To: Perl Beginners
Subject: Re: Regex find and replace - delete line

Chris Charley wrote:
>=20
> ----- Original Message ----- From: ""John W. Krahn""

<krahnj@telus.net>
>=20
> Hi John
>=20
> Shouldn't the above read like:
>=20
> for my $i ( reverse 0 .. $#file ) {
> splice @file, $i, 1 if $file[$i] =3D~ /foo/;


Yes it should, sorry about that mistake.



John
--=20
use Perl;
program
fulfillment

--=20

I tested this code

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

my @file =3D ();
@file =3D qq(foo, derek, smith, bar);
for my $i ( reverse 0 .. $#file ) {
splice @file, $i, 1 if $file[$i] =3D~ /foo/;
}
print @file;

and it prints nothing. I thought the goal was to just splice the
element that matched foo???

I changed it to=20

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

my @file =3D ();
@file =3D qq(foo, derek, smith, bar);
for my $i ( reverse 0 .. $#file ) {
splice @file, $i, 1 if $file[$i] eq "foo";
}
print @file;

and it prints
foo, derek, smith, bar

________________________________________
_________

This message is for the designated recipient only and may contain privilege=
d, proprietary, or otherwise private information. If you have received it i=
n error, please notify the sender immediately and delete the original. Any =
other use of the email by you is prohibited.

Dansk - Deutsch - Espanol - Francais - Italiano - Japanese - Nederlands - N=
orsk - Portuguese - Svenska: www.cardinalhealth.com/legal/email
D. Bolliger

2006-07-24, 6:57 pm

Smith, Derek am Montag, 24. Juli 2006 22:03:
> -----Original Message-----
> From: John W. Krahn [mailto:krahnj@telus.net]
> Sent: Monday, July 24, 2006 3:36 PM
> To: Perl Beginners
> Subject: Re: Regex find and replace - delete line
>
> Chris Charley wrote:
>
> <krahnj@telus.net>
>
>
> Yes it should, sorry about that mistake.
>
>
>
> John
> --
> use Perl;
> program
> fulfillment
>
> --
>
> I tested this code
>
> #!/usr/bin/perl
> use strict;
> use warnings;
>
> my @file = ();
> @file = qq(foo, derek, smith, bar);


Test again with

@file = qw(foo derek smith bar);

:-)

> for my $i ( reverse 0 .. $#file ) {
> splice @file, $i, 1 if $file[$i] =~ /foo/;
> }
> print @file;
>
> and it prints nothing.


The first and only element matched /foo/ and has been deleted.

> I thought the goal was to just splice the
> element that matched foo???
>
> I changed it to
>
> #!/usr/bin/perl
> use strict;
> use warnings;
>
> my @file = ();
> @file = qq(foo, derek, smith, bar);
> for my $i ( reverse 0 .. $#file ) {
> splice @file, $i, 1 if $file[$i] eq "foo";
> }
> print @file;
>
> and it prints
> foo, derek, smith, bar


The first and only element was not 'foo' and has not been deleted.

Dani
Derek Smith

2006-07-24, 6:57 pm


--=20
To unsubscribe, e-mail: beginners-unsubscribe@perl.org
For additional commands, e-mail: beginners-help@perl.org
<http://learn.perl.org/> <http://learn.perl.org/first-response>



Ahhh yes...thank you for the pointing out the oversights =3D> qw instead
of qq and removing the commas.

________________________________________
_________

This message is for the designated recipient only and may contain privilege=
d, proprietary, or otherwise private information. If you have received it i=
n error, please notify the sender immediately and delete the original. Any =
other use of the email by you is prohibited.

Dansk - Deutsch - Espanol - Francais - Italiano - Japanese - Nederlands - N=
orsk - Portuguese - Svenska: www.cardinalhealth.com/legal/email
James Turnbull

2006-07-26, 3:57 am

-----BEGIN PGP SIGNED MESSAGE-----
Hash: RIPEMD160

D. Bolliger wrote:
> Chad Perrin am Sonntag, 23. Juli 2006 14:11:
>
>
> Yes, of course it should be "ne" . . .

Thanks to all! The above solution worked perfectly.

Regards

James Turnbull

- --
James Turnbull <james@lovedthanlost.net>
- ---
Author of Pro Nagios 2.0
(http://www.amazon.com/gp/product/1590596099/)

Hardening Linux
(http://www.amazon.com/gp/product/1590594444/)
- ---
PGP Key (http://pgp.mit.edu:11371/pks/lookup...arch=0x0C42DF40)

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.3 (Darwin)

iD8DBQFExzXm9hTGvAxC30ARA+S9AJ905Cz3CpMn
AqiCq453m/tljyN4SQCfUFOY
BKE5/gyMy268joBcdpzpRJM=
=DaPD
-----END PGP SIGNATURE-----

Sponsored Links







Also available: Server administration forum archive | Web Design forum archive | Software forum archive | Hardware reviews archive

Copyright 2008 codecomments.com