Arquivo de texto para campos (colunas) a cada nésima ocorrência de uma string

2

Analisei as perguntas já respondidas, mas não vejo minha pergunta específica.

Estou criando uma planilha do Excel de configuração do Cisco Fabric e quero obter o formato correto em campos / colunas para importação.

Aqui está o formato, com informações alteradas, é claro:

zone name Zone1_HOSTNAME01 vsan XXX
  fcalias name STORAGEPORT_0 vsan XXX
    pwwn xx:xx:xx:xx:xx

  fcalias name STORAGEPORT_1 vsan XXX
    pwwn xx:xx:xx:xx:xx

  fcalias name STORAGEPORT_2 vsan XXX
    pwwn xx:xx:xx:xx:xx

zone name Zone2_HOSTNAME02 vsan XXX
  fcalias name STORAGEPORT_3 vsan XXX
    pwwn xx:xx:xx:xx:xx

  fcalias name STORAGEPORT_4 vsan XXX
    pwwn xx:xx:xx:xx:xx

  fcalias name HOSTNAME02 vsan XXX
    pwwn xx:xx:xx:xx:xx

Então, o que eu quero fazer é ter tudo em Zone name NOME DA ZONA até o espaço "vsan" em 1 campo, e então até a próxima ocorrência do início da linha com "nome da zona" colocar cada string em sua próprio campo que eu posso então "cortar" usando delimitadores para obter o que eu quero. Então, em essência, o que eu quero ter no final é:

"zone name Zone1_HOSTNAME01" "vsan" "XXX" "fcalias name" "STORAGEPORT_0 vsan XXX" "pwwn xx:xx:xx:xx:xx" "fcalias name" "STORAGEPORT_1 vsan XXX" "pwwn xx:xx:xx:xx:xx" "fcalias name" "STORAGEPORT_2 vsan XXX" "pwwn xx:xx:xx:xx:xx"

ou algo parecido. Cada espaço em branco pode estar em seu próprio campo, pois eu posso manipular as colunas depois muito mais facilmente.

O arquivo de texto tem mais de 800 linhas e algumas podem ser maiores, mas é desconhecido no momento. O maior problema é que o texto que vem depois da linha inicial que começa com "zone name ...." pode estar variando, então eu preciso traduzi-los em seus próprios campos, independentemente do que vem a seguir.

Espero que isso faça sentido e que qualquer ajuda seja muito apreciada.

    
por markizy 01.07.2016 / 18:08

3 respostas

0

O script perl a seguir exibe seu arquivo de entrada ( markizy.txt ) no formato delimitado por tabulação porque há espaços dentro dos campos.

#!/usr/bin/perl

while(<>) {
  chomp;
  s/ +(vsan|fcalias|pwwn) */\t$1 /g ;
  s/ +\t/\t/;

  if ($. > 1 && m/^zone name/) {
    print $l,"\n";
    $l = $_;
  } elsif (eof) {
    $l .= $_;
    print $l,"\n";
  } else {
    $l .= $_;
  };
};

A variável interna perl $. é o número da linha atual, portanto, o script evita a impressão (uma linha vazia) quando zone name está na primeira linha da entrada. Veja man perlvar para detalhes sobre esta e muitas outras variáveis (e seus apelidos longos como $INPUT_LINE_NUMBER para $. ).

Salve-o em um arquivo, torne-o executável com chmod +x e execute-o. por exemplo. com cat -T para mostrar as abas ( ^I ):

$ ./markizy.pl markizy.txt  | cat -T
zone name Zone1_HOSTNAME01^Ivsan XXX^Ifcalias name STORAGEPORT_0^Ivsan XXX^Ipwwn xx:xx:xx:xx:xx^Ifcalias name STORAGEPORT_1^Ivsan XXX^Ipwwn xx:xx:xx:xx:xx^Ifcalias name STORAGEPORT_2^Ivsan XXX^Ipwwn xx:xx:xx:xx:xx
zone name Zone2_HOSTNAME02^Ivsan XXX^Ifcalias name STORAGEPORT_3^Ivsan XXX^Ipwwn xx:xx:xx:xx:xx^Ifcalias name STORAGEPORT_4^Ivsan XXX^Ipwwn xx:xx:xx:xx:xx^Ifcalias name HOSTNAME02^Ivsan XXX^Ipwwn xx:xx:xx:xx:xx

O canal para cat -T está lá apenas para mostrar que a saída possui campos separados por tabulação (porque eles não parecem muito diferentes de espaços, caso contrário). Não use quando for executado de verdade, apenas redirecione para um arquivo. O Excel (ou gnumeric ou Libre Office Calc ou quase qualquer outra planilha) não deve ter dificuldade em importar um arquivo de texto separado por TAB - tem sido um recurso padrão por quase tanto tempo quanto me lembro.

Execute para real como:

./markizy.pl markizy.txt > markizy.csv

Você pode ter que dizer ao Excel que os dados são separados por tabulações em vez de separados por vírgula na importação ou podem detectar esse fato em si.

Como alternativa, se você estiver absolutamente certo de que nenhum dos campos de dados conterá vírgulas, substitua todos os \t s no script por vírgulas e separe-os por vírgula.

    
por 03.07.2016 / 12:05
0

Pode ser mais fácil, a longo prazo, fazer todo o trabalho no Excel. Eu cortei e colei seu exemplo em um arquivo de texto e o abri no Excel e obtive o seguinte:

A partir daí, você pode usar o comando global search and replace para fazer as modificações que desejar.

    
por 01.07.2016 / 21:51
0

Parecia óbvio que certos campos poderiam ser omitidos, já que isso seria explicado nas strings que eu criaria no Excel depois de importar os dados classificados. Existem opções muito melhores, mas isso levou toda a minha saída, coloquei todos os valores em ordem em uma nova linha e então removi os campos não necessários para o vsan | pwwn | 'zone name' | fcalias e deixei-me com apenas os alias de zona e membro junto com as entradas pwwn. Como todas as zonas começaram com letras maiúsculas Z, isso tornou mais simples também.

O código que eu usei em um liner foi:

grep -oP '\S+' switch01-zones-20160711 | grep -Ev 'name|vsan|^01|^02|fcalias|pwwn|zone' | awk '{printf "%s%s", (/^Zone/?rs:FS), $0; rs=RS} END{print ""}' >to-import.csv

isso me deixou com uma única linha agradável para cada zona e o alias de membro com o dispositivo www conectado também e importado para o Excel para construção de strings e tudo em questão de momentos. Espero que isso ajude alguém. Obrigado novamente @cas

    
por 18.07.2016 / 12:55