Estoy tratando de escribir un script en Perl para analizar un archivo y segregar su contenido según un criterio de coincidencia. Un archivo de muestra (por ejemplo, test.txt) se vería así:

command something something keyword something something
filepath1
filepath2
command something something something something
filepath3
filepath4
filepath5

La salida del script serían dos archivos basados ​​en el nombre del archivo de entrada para el script, test.keyword y test.nomatch.

Test.keyword tendría algo como esto:

command something something keyword something something
filepath1
filepath2

Test.nomatch tendría algo como esto:

command something something something something
filepath3
filepath4
filepath5

He intentado buscar formas de lograr esto, pero no puedo encontrar algo que me ayude. Esta es la única parte de mi guión que queda y ahora me está volviendo loco. Y sí, no soy un experto en Perl. :(

A continuación se muestra el esqueleto que tengo en este momento que está esperando esa condición de bucle dorado:

#!/usr/bin/perl -a

my $fh = shift or die "No file passed as argument for splitting!\n";
open( infile, "<$fh" ) or die $!;
open( vef_output, ">$fh.vef" ) or die $!;
open( svf_output, ">$fh.svf" ) or die $!;

$mode = 0; #0 for vef and 1 for svf

while ( my $line = <$infile> ) {
        if ( $line =~ /SOME_LIBRARY_OPTIONS/ ) {
        if ( $line =~ /\-sv/ ) {
            print {$svf_output} $line;
            $mode = 1;
        }
        else {
            print {$vef_output} $line;
            $mode = 0;
        }
        next;
    }
    if ( $mode eq 0 ) {
        print {$vef_output} $line;
        next;
    }
    else {
        print {$svf_output} $line;
        next;
    }   
}
close($vef_output);
close($svf_output);
close($file);
2
user2017152 3 mar. 2021 a las 16:21

1 respuesta

La mejor respuesta

Si bien la lógica de su código es correcta y seguramente encontrará algunos errores tipográficos restantes por su cuenta, me gustaría sugerir una modificación a su ciclo while:
Cada línea de su archivo de entrada deberá imprimirse una vez (excepto quizás para el comienzo del archivo de entrada). En lugar de establecer una marca $mode y probar eso, prefiero cambiar el identificador del archivo de salida, lo que lleva a un código más claro:

#!/usr/bin/perl
use strict;
use warnings;

my $filename = shift or die "No file passed as argument for splitting!\n";

# add filename to error message - users will like it!
open( my $infile, "<", $filename ) or die "could not open $filename: $!";
open( my $vef_output, ">","$filename.vef" )
    or die "could not open $filename.vef: $!";
open( my $svf_output, ">","$filename.svf" )
    or die "could not open $filename.svf: $!";

my $active_out;

while ( my $line = <$infile> ) {
    if ( $line =~ /SOME_LIBRARY_OPTIONS/ ) {
        $active_out = $vef_output;
    }
    # depending on your regex this conditional can be nested or not...
    if ( $line =~ /-sv/ ) {
        $active_out =  $svf_output;
    }
    next unless defined $active_out;
    print $active_out $line;
}

close($vef_output);
close($svf_output);
close($infile);
2
clamp 3 mar. 2021 a las 19:32