Mach aus drei Zeilen eine ...

Mach aus drei Zeilen eine ...

am 08.10.2007 12:34:22 von Oliver Beck

Mahzeit,

ich bekomme eine Datei mit folgendem Inhalt (unbestimmte Laenge, was ja
egal sein sollte):

-----8<--schnipp-->8-----
X -123.456
Y +23.456
Z +0.123
X +456.789
Y -56.789
Z -0.123
-----8<--schnapp-->8-----

Es gibt immer eine Paarung von X, Y und Z.

Nun moechte ich die einzelnen Koordianten X, Y und Z in eine Zeile
bannen. Dies habe ich bisher folgendermassen geloest:

- Datei einlesen (open)

- fuer jede Zeile ein Vergleich (if) machen, ob X, Y oder Z

- mittels split() die Werte von den Bezeichnern trennen und Werte
in eine neue Variable schreiben

Nun will ich die einzelne Zeile nur dann ausgeben, wenn alle drei
Koordinaten in der Variablen aufgefuehrt sind, also, wenn sie den Inhalt
aehnlich '+456.789, -56.789, -0.123' hat.

Dies loese ich mit folgendem Match:
m/
(\-|\+)([0-9*])(\.*)([0-9*]*)\,
(\-|\+)([0-9*])(\.*)([0-9*]*)\,
(\-|\+)([0-9*])(\.*)([0-9*]*)
/

Das komplette Script:

-----8<--schnipp-->8-----

use warnings;
use strict;
use vars qw/$combined $debug/;

$debug = 1;

open(INFILE,"
while () {

if ($_ =~ m/^X/)
{
chomp;
my ($coord, $val) = split(/\ /);
$combined = $val;
print "$coord hat den Wert $val | \$combined enthaelt $combined\n" if
$debug;
}

if ($_ =~ m/^Y/)
{
chomp;
my ($coord, $val) = split(/\ /);
$combined = "$combined, $val";
print "$coord hat den Wert $val | \$combined enthaelt $combined\n"
if $debug; }

if ($_ =~ m/^Z/)
{
chomp;
my ($coord, $val) = split(/\ /);
$combined = "$combined, $val";
print "$coord hat den Wert $val | \$combined enthaelt $combined\n"
if $debug; }

if ($combined =~ m/(\-|\+)([0-9*])(\.*)[0-9*]*\,
(\-|\+)([0-9*])(\.*)[0-9*]*\,
(\-|\+)([0-9*])(\.*)[0-9*]*/)
{
print "$combined\n";
}

}

close INFILE;


-----8<--schnapp-->8-----

Der Match muss noch zusammengefasst werden ... passte leider nicht in
die 72 Zeichen :)

Ich bin fast der Meinung, das es einfach nur grauenhaft aussieht ...
es muss doch eine schoenere Moeglichkeit geben. Aber mein Wissensstand
gibt mir noch keine andere Loesung vor. Es klappt soweit. Nur wollte ich
fragen, ob es da nicht etwas schoeneres gibt.



Mit freundlichen Gruessen/Best Regards Oliver Beck

--
/"\ -ASCII-Ribbon-Campaign- |
\ / Against HTML Mail |
X | -- German GNU/Hurd documentation --
/ \ | - http://de-hurd-doc.berlios.de -

Re: Mach aus drei Zeilen eine ...

am 08.10.2007 12:41:27 von Frank Seitz

Oliver Beck wrote:
>
> Ich bin fast der Meinung, das es einfach nur grauenhaft aussieht ...

Ja.

> es muss doch eine schoenere Moeglichkeit geben. Aber mein Wissensstand
> gibt mir noch keine andere Loesung vor. Es klappt soweit. Nur wollte ich
> fragen, ob es da nicht etwas schoeneres gibt.

o Verwende drei Variable
o Weise diese in Abhängikeit vom Bezeichner zu
o Teste mit defined
o Setze die Variable auf undef, wenn Datensatz verarbeitet

Grüße
Frank
--
Dipl.-Inform. Frank Seitz; http://www.fseitz.de/
Anwendungen für Ihr Internet und Intranet
Tel: 04103/180301; Fax: -02; Industriestr. 31, 22880 Wedel

Re: Mach aus drei Zeilen eine ...

am 08.10.2007 14:39:19 von Wolf Behrenhoff

Oliver Beck schrieb:
> Mahzeit,
>
> ich bekomme eine Datei mit folgendem Inhalt (unbestimmte Laenge, was ja
> egal sein sollte):
>
> -----8<--schnipp-->8-----
> X -123.456
> Y +23.456
> Z +0.123
> X +456.789
> Y -56.789
> Z -0.123
> -----8<--schnapp-->8-----
>
> Es gibt immer eine Paarung von X, Y und Z.
>
> Nun moechte ich die einzelnen Koordianten X, Y und Z in eine Zeile
> bannen. Dies habe ich bisher folgendermassen geloest:


Hallo,

suchst du sowas hier:
--8<-------------------------
undef $/;
$daten = ;

$rest='\s+([+-]\d+(?:\.\d+))';
while ($daten =~ s/^X$rest\nY$rest\nZ$rest$/Q/ms) {
print "Passt: $1 $2 $3\n";
}

__DATA__
X -123.456
Y +23.456
Z +0.123
X +456.789
Y -56.789
Z -0.123
--8<-------------------------

Wolf

Re: Mach aus drei Zeilen eine ...

am 08.10.2007 17:26:51 von Mirco Wahab

Oliver Beck wrote:
> if ($combined =~ m/(\-|\+)([0-9*])(\.*)[0-9*]*\,
> (\-|\+)([0-9*])(\.*)[0-9*]*\,
> (\-|\+)([0-9*])(\.*)[0-9*]*/)
> {
> print "$combined\n";
> }
>
> Ich bin fast der Meinung, das es einfach nur grauenhaft aussieht ...
> es muss doch eine schoenere Moeglichkeit geben. Aber mein Wissensstand
> gibt mir noch keine andere Loesung vor. Es klappt soweit. Nur wollte ich
> fragen, ob es da nicht etwas schoeneres gibt.

Unter Unix:

perl -0777 -lane 'print("@F[1,3,5]\n"),splice(@F,0,6)while@F' testdaten1.txt

und unter Windows:

perl -0777 -lane "print(qq{@F[1,3,5]\n}),splice(@F,0,6)while@F" testdaten1.txt

wenn das File jeweils mit der X-Zeile "X nn.nn" anfängt.

Viele Grüße

M.