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-----
|
|
|
|
|