pre entendimento do código para processamento de texto

1

Alguém poderia me explicar isso abaixo do código sed

sed -n '
/Policy Name:/! d
    s/.*:\s\+//
    h
    :1
    n
    /Active:\s*no/d
    /HW\//!b1
    :2
    s/.*\s\(\S*\)\s*//
    G
    s/\n/\t/p
    n
    /^\s*$\|Include:/! b2
    '

Eu quero editar para adicionar "Tipo de política:" informações, quando eu substituí-lo com "Nome da política:" funciona bem, no entanto, quando eu adiciono uma seção como abaixo, não funciona, obviamente, porque estou tentando sem compreensão.

sed -n '
/Policy Name:/! d
    s/.*:\s\+//
    h
    :1
    n
/Policy Type:/! d
    s/.*:\s\+//
    h
    :1
    n
    /Active:\s*no/d
    /HW\//!b1
    :2
    s/.*\s\(\S*\)\s*//
    G
    s/\n/\t/p
    n
    /^\s*$\|Include:/! b2
    '

Além disso, eu tenho uma solução para o código equivalente do AIX abaixo do mesmo fórum, mesmo que eu precise entendê-lo para editá-lo para adicionar o tipo de política.

# define constants
SPC='echo x | tr x '0''
TAB='echo x | tr x '1''
 NL=

# custom regex for...
s="[$SPC$TAB]";   # horizontal whitespace
S="[^$SPC$TAB]";  # non-whitespace

# POSIX compliant sed code...
sed -ne "
   /Policy Name:/!d

   s/.*:$s\{1,\}//
   h

   :1
      n
      /Active:$s*no/d
   /HW\//!b1

   :2
      s/.*$s\($S*\)$s*//
      G
      s/\n/$TAB/p
      n
      /^$s*\$/d
      /Include:/d
   b2
"  yourfile

Arquivo de entrada

Policy Name:       Today

  Policy Type:       Standard
  Active:              yes
  Effective date:      01/24/2014 11:17:05
  Client Encrypt:      no
  LC/CY/Custmr:  EU         NY  Cindy
                 BU         CA  Victor
                 GU         MI  Bob
  Include:
Policy Name:       Tomorrow

  Policy Type:       Oracle
  Active:              yes
  Effective date:      01/26/2014 11:17:05
  Client Encrypt:      no
  LC/CY/Custmr:  MU         LA  Martha
                 EU         CA  Sam
  Include:
Policy Name:       Yesterday

  Policy Type:       Oracle
  Active:              no
  Effective date:      01/21/2014 11:17:05
  Client Encrypt:      no
  LC/CY/Custmr:  NV         IL  Joe

  Include:'

Saída desejada

Cindy    Today     Standard
Victor   Today     Standard
Bob      Today     Standard
Martha   Tomorrow  Oracle
Sam      Tomorrow  Oracle
    
por Sid 01.06.2017 / 14:30

1 resposta

3

Ok, vamos fazer isso passo a passo:

sed -n '

A opção -n torna sed output nada, a menos que seja dito

/Policy Name:/! d

Todas as linhas que não contêm Policy name: são excluídas. O restante do script é processado somente nos loops a seguir.

s/.*:\s\+//
h

Isso remove tudo até o : e os espaços à direita e coloca o restante no buffer de suspensão para uso posterior.

:1
n

Este é o começo de um loop lendo novas linhas

/Active:\s*no/d

Linhas com esse padrão são removidas, então obviamente não há interesse em inativos

/HW\//!b1

E agora, fazemos um loop para :1 se a linha não contiver HW/

:2
s/.*\s\(\S*\)\s*//

Começando o próximo loop, remova tudo, exceto a última seqüência de não-brancos.

G
s/\n/\t/p

Em seguida, anexe o nome da política mantido no buffer de retenção, separado por uma guia e imprima essa linha

n
/^\s*$\|Include:/! b2
'

e isso se repete com as próximas linhas até atingirmos o padrão fornecido.

Você deve observar que esse é um código altamente não portátil que não funciona em muitas sed versões.

Editar: Para adicionar o tipo de política como uma terceira coluna, você deve adicionar essa linha ao script antes ou depois do Active: check:

/Policy Type:/{s/.*:\s*//;H;}

Ou seja: se a linha contiver a cadeia, execute os comandos entre {} . Esses comandos removem a parte até : e espaços em branco finais e anexam o restante da linha (que deve conter o tipo de política) ao buffer de armazenamento. Assim, o buffer de espera contém nome e tipo de política, separados por uma nova linha. Portanto, quando acrescentarmos isso com G , haverá duas novas linhas a serem substituídas, então o comando de substituição precisa obter o sinalizador g para substituir todas as ocorrências:

s/\n/\t/gp

O script do AIX é basicamente o mesmo, mas evita extensões do GNU para expressões regulares. Principalmente as variáveis de uso para corresponder aos espaços ou guias brancas, pois \t não funcionará em todos os sed flavors, assim como + para "um ou mais" precisa ser substituído por \{1,\}

    
por 01.06.2017 / 16:51