Sziasztok,
perlben kellene irnom egy scriptet, ami kitorli a sorvege karaktert az adott sorbol akkor, ha a kovetkezo sor elso karaktere nem "2 " (marmint nem 2-es szam utana egy space-szel). Valaki segitene picit, sajnos a normal karakterkicserelos cuccok nem akarnak mukodni (bar lehet hogy csak en rontom el). Koszi elore is
Z
- 1165 megtekintés
Hozzászólások
Van erre perlben egy chomp() nevu fuggveny.
--
Fontos feladatot soha ne bizz olyan gepre, amit egyedul is fel tudsz emelni!
- A hozzászóláshoz be kell jelentkezni
Koszi a gyors valaszt, mindjart meg is nezem.
Megneztem, csak az tovabbra sem vilagos, hogy hogyan csinaljam meg a feltetelt a kovetkezo sorra, ha esetleg ebben tudnal meg segiteni, megkoszonnem.
A felallas az, hogy van egy nagy szoveges fajl, amiben elcsuszott parezer sor (extra sortoresek miatt). Minden sor alapbol egy 2-essel es egy space-szel kezdodik, amennyiben nem, akkor az azert van, mert elcsuszott, tehat a megelozo sor vegerol ki kell venni a sorvege karaktert, hogy jo legyen. Ha esetleg ebben tudnal meg segiteni, megkoszonnem valami virtualis sorrel :) Koszi
Z
- A hozzászóláshoz be kell jelentkezni
Szerintem ugy, hogy vegigmesz a fileon, megtartod az utolso 2 sort valami valtozoban, ha a 2. elso 2 karaktere nem egyezik a megadottal (substr vagy index), akkor concat-eled oket, es ugy irod ki, egyebkent meg az elsot csak onmagaban, a 2. meg mehet az elso helyere.
--
Fontos feladatot soha ne bizz olyan gepre, amit egyedul is fel tudsz emelni!
- A hozzászóláshoz be kell jelentkezni
Igen, zamboriz megoldasa is ezen alapul. Koszi szepen!
- A hozzászóláshoz be kell jelentkezni
open( IN, '<', 'test.in' );
open( OUT, '>', 'test.out' );
$elozo=<IN>;
chomp($elozo);
while( $sor=<IN> ){
chomp($sor);
unless( $sor =~ /^2\s/ ){
$elozo .= $sor;
}
else{
print OUT $elozo, "\n";
$elozo = $sor;
}
}
print OUT $elozo, "\n";
close( IN );
close( OUT );
- A hozzászóláshoz be kell jelentkezni
Koszi szepen, ez jo lesz, csak be kell idomitani a dosos sorvege karakterekre (a CR-t nem veszi le, csak az LF-et) de ezzel mar remelem meg tudok kuzdeni :)
- A hozzászóláshoz be kell jelentkezni
Ez lett a vege (tudom lehetne szebben is, de mukodik) koszi mindkettotoknek a segitseget
open( IN, '<', 'test.in' );
open( OUT, '>', 'test.out' );
$elozo=;
chomp($elozo);
chop($elozo);
while( $sor= ){
chomp($sor);
chop($sor);
unless( $sor =~ /^2\s/ ){
$elozo .= $sor;
}
else{
print OUT $elozo, "\r\n";
$elozo = $sor;
}
}
print OUT $elozo, "\r\n";
close( IN );
close( OUT );
- A hozzászóláshoz be kell jelentkezni
Kis huszáros vágással, illetve csalással egész kurtára szabható ez a bizonyos szkript - tán még a tankéremnek is tetszhet, ha olyan.
$file = ....
$txt = `cat $file`;
$txt =~ s/\n([^2]|2[^ ])/$1/g;
print $txt;
A csalás persze az egész fájl egy sztringbe konkatenálása külső paranccsal.
- A hozzászóláshoz be kell jelentkezni
Előre elnézést a kötözködésért, de feltett szándékom programozót nevelni azokból is, akik szkriptnyelvekkel foglalkoznak.
A kolléga megoldásában a fájl teljes tartalmának sztringbe olvasása (slurping) nem a külső parancs miatt csalás. A külső parancs használata alapvetően minden helyzetben kerülendő, mert:
1. új processzt indítasz, ami drága
2. legtöbbször code injectre ad lehetőséget
A csalás abban áll, hogy memóriába olvassa a teljes fájl tartalmát, ami fájlmérettől függően vagy elfogadható, vagy nem. Az igaz, hogy rövidebb kódot eredményez (ami amúgy nem feltétlenül cél).
A slurpingre egy szép megoldás:
open my $fh, $ARGV[0] or die "Unable to open file: $!\n";
local $/;
my $content = <$fh>;
close $fh;
$content =~ s/\n([^2]|2[^ ])/$1/g;
print "$content\n";
További megjegyzések, és ezek közül bizonyosak mások megoldásait is érintik:
1. Kerüld a globális névteret használó változókat (open FILE, ...). open esetén használj lokálisan deklarált scalar filehandlet. Lásd:
sub doSomething
{
open FILE, "filename1";
# ...
close FILE;
}
# ...
open FILE, "filename2";
doSomething();
# ... Itt valami fontosat végzünk
close FILE;
Ezzel az a gond, hogy a doSomething-ot egy másik programozó írta 5 évvel ezelőtt, és Te már csak fekete dobozként szeretnél rá tekinteni. Nem teheted, és a fenti kód nem is fogja azt tenni, amire számítasz, mert a doSomething felülírja a FILE nevű filehandlet, így a fontosat nem végezzük el, arról nem is beszélve, hogy a szubrutinon kívül megnyitott fájlt soha nem zárjuk le, mert az a close már nem arra vonatkozik...
2. Az előre definiált "magic" változókkal való babrálást végezzük lokálisan (erre való a local kulcsszó :-))
3. Ha már Perl, perldoc.perl.org-ot tessék forgatni. Hasznos.
- A hozzászóláshoz be kell jelentkezni