Thread neuerer vergleich Perl mit awk: awk /start/,/end/ '{print $2}' (5 answers)
Opened by lichtkind at 2006-01-14 19:32

coax
 2006-01-14 21:25
#61898 #61898
User since
2003-08-11
457 Artikel
BenutzerIn
[default_avatar]
Jo, die if-Anweisung ist etwas ungewoehnlich, sie verwendet den Bereichsoperator .., aber anders als man ihn in foreach-Schleifen, etc. kennt, naemlich im skalaren Kontext und dann verhaelt er sich so wie der Komma-Operator bei awk.
Ist der linke Operand wahr ist der gesamte Ausdruck wahr und bleibt so lange wahr bis der rechte Operand wahr wird, dann ist er wieder unwahr (falsch). Der linke Operand wird nur ausgewertet wenn der Operator unwahr ist und der rechte Operand nur wenn der Operator wahr ist.
Funktioniert, simplifiziert, in etwa so
Code: (dl )
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
#!/usr/bin/perl

 use strict;
 use warnings;

 use constant TRUE => 1;
 use constant FALSE => 0;

 my $state = FALSE;
 while(<DATA>) {

     unless( $state == TRUE ) {   # wenn Operator unwahr ...
              $state = TRUE if /start/;  # ... wahr setzen wenn linker Operand wahr
     } else {                    # ansonsten ... ( wenn Operator nicht wahr )
         $state = FALSE if /end/;   # ... falsch setzen wenn rechter Operand wahr

         print if $state == TRUE;
     }
 }

_ _DATA_ _
 nichts
 nichts
start
 eins
 zwei
 drei
end
 nichts
 nichts
start
 vier
 fuenf
 sechs
end

Hoffe es ist etwas verstaendlich, wenn nicht, dann hilft
perldoc perlop (Range Operator), bzw. das Kamelbuch (Kap. 2 - Bereichsoperator) und es steht noch was im Kochbuch (Kap. 6 - Mustererkennung - Einen Bereich extrahieren).

Zum besseren Verstaendnis hab ich daraus eine Sub gemacht (haette ich gleich tun sollen).
Code: (dl )
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
#!/usr/bin/perl

use strict;
use warnings;

while(<DATA>) {
    print if range_op( scalar(/start/), scalar(/end/) );
}

BEGIN {
my( $true, $false ) = ( 1, 0 );

my $state = $false;

sub range_op {
    my( $term_l, $term_r ) = @_;

    if( $state == $true ) {
        $state = $false if $term_r == $true;

        return $state;
    }
   
    $state = $true if $term_l == $true;
    return 0;
}

}
_ _DATA_ _
nichts
nichts
start
eins
zwei
drei
end
nichts
nichts
start
vier
fuenf
sechs
end
\n\n

<!--EDIT|coax|1137273982-->
,,Das perlt aber heute wieder...'' -- Dittsche

View full thread neuerer vergleich Perl mit awk: awk /start/,/end/ '{print $2}'