Script Perl para dividir um arquivo baseado em um padrão em um determinado deslocamento

1

Eu preciso da sua ajuda para ter uma ideia de como dividir um arquivo grande em pequenos sub-arquivos, como dito no exemplo abaixo.

Critérios é que estamos olhando para o offset 30 (31 bytes para 2 bytes). Se o offset contiver 0A então o registro deve ser copiado para o arquivo A, se for 0B @ 32 então ele deve ser copiado para o arquivo B e se for um 0C então ele deve ser copiado para o arquivo C

Exemplo de arquivo de entrada:

1111111111111111111111111111110A111111111111111111111111111111
1111111111111111111111111111110B111111111111111111
1111111111111111111111111111110C11111111111111111111111
1111111111111111111111111111110A111111111111111111111111111111
1111111111111111111111111111110B111111111111111111
1111111111111111111111111111110A111111111111111111111111111111
1111111111111111111111111111110B111111111111111111

Arquivo de saída A:

1111111111111111111111111111110A111111111111111111111111111111
1111111111111111111111111111110A111111111111111111111111111111
1111111111111111111111111111110A111111111111111111111111111111

Arquivo de saída B:

1111111111111111111111111111110B111111111111111111
1111111111111111111111111111110B111111111111111111
1111111111111111111111111111110B111111111111111111

Arquivo de saída C:

1111111111111111111111111111110C11111111111111111111111
    
por santosh 04.05.2016 / 23:35

2 respostas

2

Para cada linha, você pode usar apenas substr($line,30,2) para obter os dois caracteres desejados. Então, algo parecido com

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

open(my $file1,">file1");
open(my $file2,">file2");
open(my $file3,">file3");
while(<>)
{
  my $ch=substr($_,30,2);
     if ($ch eq '0A') { print $file1 $_; }
  elsif ($ch eq '0B') { print $file2 $_; }
  elsif ($ch eq '0C') { print $file3 $_; }
  else { print "Bad line skipped: $_"; }
}

Podemos ver isso em ação:

$ cat input 
1111111111111111111111111111110A111111111111111111111111111111
1111111111111111111111111111110B111111111111111111
1111111111111111111111111111110C11111111111111111111111
1111111111111111111111111111110A111111111111111111111111111111
1111111111111111111111111111110B111111111111111111
1111111111111111111111111111110A111111111111111111111111111111
1111111111111111111111111111110B111111111111111111
$ ./script input 
$ cat file1
1111111111111111111111111111110A111111111111111111111111111111
1111111111111111111111111111110A111111111111111111111111111111
1111111111111111111111111111110A111111111111111111111111111111
$ cat file2
1111111111111111111111111111110B111111111111111111
1111111111111111111111111111110B111111111111111111
1111111111111111111111111111110B111111111111111111
$ cat file3
1111111111111111111111111111110C11111111111111111111111
    
por 04.05.2016 / 23:50
0
$ perl -ne '
    $filename = substr($_,30,2); 
    open $fh{$filename}, ">", $filename unless exists $fh{$filename}; 
    print {$fh{$filename}} $_
' file

$ cat 0A
1111111111111111111111111111110A111111111111111111111111111111
1111111111111111111111111111110A111111111111111111111111111111
1111111111111111111111111111110A111111111111111111111111111111

$ cat 0B
1111111111111111111111111111110B111111111111111111
1111111111111111111111111111110B111111111111111111
1111111111111111111111111111110B111111111111111111

$ cat 0C
1111111111111111111111111111110C11111111111111111111111
    
por 06.05.2016 / 15:56