Schrift
Wiki:Tipp zum Debugging: use Data::Dumper; local $Data::Dumper::Useqq = 1; print Dumper \@var;
[thread]6951[/thread]

best.Zeile + darauffolgende Zeilen löschen



<< |< 1 2 >| >> 18 Einträge, 2 Seiten
Gast Gast
 2005-05-03 11:38
#54486 #54486
Hi !

Ich versuche mich gerade in Perl und hab ein kleines Problem:
Und zwar lese ich eine Datei ein und möchte diese bearbeiten. Das ganze soll dann so funktionieren, dass nach dem String "NOID" gesucht werden soll, wenn dieser String gefunden wird, soll die Zeile, die diesen String beinhaltet und die 3 darauffolgenden Zeilen gelöscht werden. Ist das einfach zu realisieren?
Vielen Dank,
Stefan
renee
 2005-05-03 12:09
#54487 #54487
User since
2003-08-04
14371 Artikel
ModeratorIn
[Homepage] [default_avatar]
Eine der vielen Möglichkeiten wäre:
Code: (dl )
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#! /usr/bin/perl

use strict;
use warnings;
use Tie::File;

my $file = "./test.txt";
my $index;

open(FILE,"<$file") or die $!;
while(my $line = <FILE>){
$index = $. if($line =~ /NOID/);
}
close FILE;

if(defined $index){
tie my @array,'Tie::File',$file or die $!;
splice(@array,$index-1,4);
untie @array;
}
OTRS-Erweiterungen (http://feature-addons.de/)
Frankfurt Perlmongers (http://frankfurt.pm/)
--

Unterlagen OTRS-Workshop 2012: http://otrs.perl-services.de/workshop.html
Perl-Entwicklung: http://perl-services.de/
Crian
 2005-05-03 12:10
#54488 #54488
User since
2003-08-04
5871 Artikel
ModeratorIn
[Homepage]
user image
>Ist das einfach zu realisieren?

ja




.






.





.





War das die Antwort, die Du hören wolltest? ;)
Was ist denn genau das Problem? Was hast Du versucht?
Soll die Datei dabei kopiert werden? Oder durch die bereinigte Version ersetzt?
s--Pevna-;s.([a-z]).chr((ord($1)-84)%26+97).gee; s^([A-Z])^chr((ord($1)-52)%26+65)^gee;print;

use strict; use warnings; Link zu meiner Perlseite
Dubu
 2005-05-03 12:51
#54489 #54489
User since
2003-08-04
2145 Artikel
ModeratorIn + EditorIn

user image
Code: (dl )
perl -ne '$cnt=4 if /NOID/; print unless $cnt && $cnt--;' datei_alt.txt > datei_neu.txt
\n\n

<!--EDIT|Dubu|1115110344-->
StefanJ
 2005-05-03 13:03
#54490 #54490
User since
2005-05-03
35 Artikel
BenutzerIn
[default_avatar]
Danke für die schnellen antworten, kann es aber gerade nicht aus zeitmangel testen. Aber ich denke das ist genau die Lösung die ich gesucht habe. Meld mich später nochmal!
Gruss,Stefan
Strat
 2005-05-03 15:15
#54491 #54491
User since
2003-08-04
5246 Artikel
ModeratorIn
[Homepage] [default_avatar]
Wenn man die Datei nur einmal oeffnen will, geht's auch so:
Code: (dl )
1
2
3
4
5
6
7
8
9
10
11
12
13
14
use strict;
use warnings;
use Tie::File;

my $file = "./test.txt";

tie my @array,'Tie::File',$file or die $!;
my $index = undef;
foreach (0..$#array) {
 $index = $_, last if $array[$_] =~ /NOID/;
}

splice(@array,$index,4) if defined($index);
untie @array;
\n\n

<!--EDIT|Strat|1115118968-->
perl -le "s::*erlco'unaty.'.dk':e,y;*kn:ai;penmic;;print"
http://www.fabiani.net/
StefanJ
 2005-05-03 16:52
#54492 #54492
User since
2005-05-03
35 Artikel
BenutzerIn
[default_avatar]
[quote=renee,03.05.2005, 10:09]Eine der vielen Möglichkeiten wäre:
Code: (dl )
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#! /usr/bin/perl

use strict;
use warnings;
use Tie::File;

my $file = "./test.txt";
my $index;

open(FILE,"<$file") or die $!;
while(my $line = <FILE>){
 $index = $. if($line =~ /NOID/);
}
close FILE;

if(defined $index){
 tie my @array,'Tie::File',$file or die $!;
 splice(@array,$index-1,4);
 untie @array;
}
[/quote]

Also wenn ich diesen Block kopiere und den Dateinamen entsprechend anpasse, löscht er nur beim ersten gefundenen "NOID" die Zeile+die 3 darauffolgenden. die anderen 300 Einträge mit "NOID" bleiben bestehen ?!
da hab ich wohl was falsch gemacht !? Eine Idee was ??
Ronnie
 2005-05-03 17:35
#54493 #54493
User since
2003-08-14
2022 Artikel
BenutzerIn
[default_avatar]
[quote=StefanJ,03.05.2005, 14:52]Also wenn ich diesen Block kopiere und den Dateinamen entsprechend anpasse, löscht er nur beim ersten gefundenen "NOID" die Zeile+die 3 darauffolgenden. die anderen 300 Einträge mit "NOID" bleiben bestehen ?!
da hab ich wohl was falsch gemacht !? Eine Idee was ??[/quote]
Die Lösung von Dubu finde ich sehr ansprechend, aber wenn du mit Tie::File arbeiten willst, musst du ein Array von Indizes bauen und dann von hinten nach vorne raussplicen.
StefanJ
 2005-05-03 18:07
#54494 #54494
User since
2005-05-03
35 Artikel
BenutzerIn
[default_avatar]
[quote=Dubu,03.05.2005, 10:51]
Code: (dl )
perl -ne '$cnt=4 if /NOID/; print unless $cnt && $cnt--;' datei_alt.txt > datei_neu.txt
[/quote]
Ja, ich finde diese Lösung auch sehr elegant, weil sie kurz ist, nur versteh ich sie leider nicht. Das Problem ist, dass ich seit wenigen Stunden Perl ausprobiere--> Noob
Ich denke auch bei dieser Lösung benötigt man ein Array und muss eine Schleife basteln, weil ja "NOID" sehr oft in der Textdatei erscheint und nicht einmal !
Leider kapier ich nicht wozu das ' -ne ' gut ist, und auch nicht wieso der "print-Befehl" getrennt ist durch ein " ; "(was ja eigentloich bedeutet dass die Zeile zuende ist ?) mit der Datei in die geschrieben werden soll !
Vielleicht erbarmt sich ja nochmal einer, mir das zu erklären...
Trotzdem danke,
Stefan
Ronnie
 2005-05-03 18:33
#54495 #54495
User since
2003-08-14
2022 Artikel
BenutzerIn
[default_avatar]
Das -ne veranlasst Perl den nachfolgenden Code für jede Zeile der übergebenen Datei auszuführen. Wie du bereits erkannt hast trennt das Semikolon einzelne Befehle (zumeist am Zeilenende).
$cnt=4 if /NOID/; setzt eine Zählervariable wenn Perl ein 'NOID' sieht (Matchingoperator).
print unless $cnt && $cnt--; gibt die aktuelle Zeile aus solange die Zählvariable NICHT einen Wert hat und dekrementiert anschließend die Zählvariable (aber nur solange sie einen Wert hat - durch die logische Verundung der Befehle).\n\n

<!--EDIT|Ronnie|1115131021-->
<< |< 1 2 >| >> 18 Einträge, 2 Seiten



View all threads created 2005-05-03 11:38.