Como extrair uma linha com base nos vários campos no perl

1

Como extrair uma linha com base nos vários campos em perl

Eu tenho abaixo file: file1.txt e quero extrair linha com base em correspondência composta de vários campos, o que significa que, se a linha tiver uma combinação de todos esses campos, apenas deverá extrair a linha que contém esses campos

tcp
10.11.38.224
10.185.34.240
9012

arquivo1.txt

access firewall udp 10.14.90.111 240.230.111.222 10.13.45.21 255.255.230.240 eq 8443
access firewall tcp 10.11.38.224 255.233.212.111 10.185.34.240 244.255.240.211 eq 9012
#!/usr/bin/perl

open(SOURCE,"<file1.txt");
while (my @gitLines_mst = <SOURCE>)
{
my $fld0 = "tcp";
my $sIP = "10.11.38.224";
my $dIP = "10.185.34.240";
my $fld5 = "9012";
print "$fld0";
my @llll = grep {"/$fld0/" && "/$sIP/" && "/$dIP/" && "/$fld5"} @gitLines_mst;
print "here please: @llll \n";
}

Eu escrevi o script acima, listando a linha correspondente junto com todo o conteúdo do arquivo novamente

minha saída:

access firewall udp 10.14.90.111 240.230.111.222 10.13.45.21 255.255.230.240 eq 8443
access firewall tcp 10.11.38.224 255.233.212.111 10.185.34.240 244.255.240.211 eq 9012

Eu até removi aspas duplas enquanto procurava e tentava:

my @llll = grep {/$fld0/ && /$sIP/ && /$dIP/ && /$fld5} @gitLines_mst;

Eu recebi o erro:

Search pattern not terminated at ./sample line 11.

Minha saída desejada é:

access firewall tcp 10.11.38.224 255.233.212.111 10.185.34.240 244.255.240.211 eq 9012
    
por Vibes 16.01.2018 / 08:00

1 resposta

2

#!/usr/bin/perl

while(<>) {
  @F = split;  # split input line into array @F using whitespace as separator.
  # Note: perl arrays start from 0, not 1.

  print if (($F[2] eq 'tcp') && 
            ($F[3] eq '10.11.38.224') &&
            ($F[5] eq '10.185.34.240') &&
            ($F[8] == 9012))
}

(que if declaração poderia ser tudo em uma linha, mas é muito mais fácil de ler formatado como este)

Guarde isto em, por exemplo myscript.pl , torne executável com chmod +x myscript.pl e execute como:

$ ./myscript.pl file1.txt 
access firewall tcp 10.11.38.224 255.233.212.111 10.185.34.240 244.255.240.211 eq 9012

Este programa não é muito útil, no entanto. Realmente só faz uma coisa, imprimir linhas combinando exatamente com os quatro critérios de busca.

Nota: como regra geral, para programas como este, é melhor escrevê-los como um filtro - isto é, obter entrada de stdin e / ou qualquer nome de arquivo mencionado na linha de comando do que codificar um nome de arquivo específico no arquivo. programa.

Dessa forma, ele pode ser usado com qualquer nome de arquivo ou pode receber dados de grep ou awk ou alguma outra saída do programa.

O identificador de arquivo <> no perl faz exatamente isso. Ele pegará a entrada de nomes de arquivos stdin AND (se houver) dados como argumentos na linha de comandos.   while (<>) { ...code... } é algo que você verá muito em programas perl que pesquisam, reformatam, extraem dados e fazem outras coisas para stdin e / ou entrada de arquivos.

com base na sua pergunta semelhante de ontem, se você quiser variáveis com nomes significativos em vez de apenas uma matriz @F , você pode escrever assim:

#!/usr/bin/perl

while(<>) {
  my ($access, $something, $proto, $srcIP, $srcmask,
      $destIP, $destmask, $eq, $port) = split;

  print if (($proto  eq 'tcp') && 
            ($srcIP  eq '10.11.38.224') &&
            ($destIP eq '10.185.34.240') &&
            ($port   == 9012))
}

e você pode usar undef para qualquer campo com o qual não se preocupe e não pretenda usar. por exemplo,

  my (undef, undef, $proto, $srcIP, undef, $destIP, undef, undef, $port) = split;

BTW, algo assim poderia ser feito facilmente em awk também:

$ awk '$3=="tcp" && $4=="10.11.38.224" && $6=="10.185.34.240" && $9==9012' file1.txt 
access firewall 1 10.11.38.224 255.233.212.111 1 244.255.240.211 eq 9012

ou como um perl one-liner:

$ perl -lane 'print if $F[2] eq "tcp" && $F[3] eq "10.11.38.224" && $F[5] eq "10.185.34.240" && $F[8] == 9012' file1.txt 
access firewall tcp 10.11.38.224 255.233.212.111 10.185.34.240 244.255.240.211 eq 9012
    
por 16.01.2018 / 08:23

Tags