Eu quero pesquisar e substituir um padrão

1

Eu quero pesquisar cada registro (registros são definidos por linhas em branco) em um arquivo para o padrão NAME#AAAA . Se corresponder, insira um # na frente do age do registro e insira uma linha age NIL no final do registro.

ARQUIVO DE ENTRADA:

NAME#AAAA
STD 1
SEC A
AGE 5

NAME#BBBB
STD 2
SEC B
AGE 6


NAME#CCCC
STD 3
SEC C
AGE 7

NAME#AAAA
STD 4
AGE 9


NAME#AAAA
STD 7
SEC A
AGE 12

RESULTADO ESPERADO

NAME#AAAA
STD 1
SEC A
#AGE 5
AGE NIL

NAME#BBBB
STD 2
SEC B
AGE 6

NAME#CCCC
STD 3
SEC C
AGE 7


NAME#AAAA
STD 4
#AGE 9
AGE NIL


NAME#AAAA
STD 7
SEC A
#AGE 12
AGE NIL
    
por user4432340 19.04.2016 / 15:46

1 resposta

0

Sempre que você vir registros separados por linhas em branco ("parágrafos", se quiser), o "modo de parágrafo" de Perl é geralmente uma boa solução:

$ perl -00lpe 'if(/NAME#AAAA/){s/\bAGE\s/#$&/; s/$/\nAGE NIL/;}' file
NAME#AAAA
STD 1
SEC A
#AGE 5
AGE NIL

NAME#BBBB
STD 2
SEC B
AGE 6

NAME#CCCC
STD 3
SEC C
AGE 7

NAME#AAAA
STD 4
#AGE 9
AGE NIL

NAME#AAAA
STD 7
SEC A
#AGE 12
AGE NIL

Explicação

  • -00 : ativa o modo de parágrafo do perl, onde cada "parágrafo" (grupo de linhas não-brancas até um em branco) é tratado como uma "linha".
  • -l : remove as novas linhas à direita de cada registro de entrada (cada parágrafo) e adiciona uma nova linha a cada chamada print . -pe : imprime cada registro de entrada após aplicar o script dado por -e a ele.

Assim, esses sinalizadores fazem perl ler o arquivo de entrada, aplicando o script a cada registro e imprimindo o resultado. O script em si faz:

  • if(/NAME#AAAA/) : se este registro corresponder a NAME#AAAA .
  • s/\bAGE\s/#$&/ : O s/foo/bar/ é o operador de substituição. Ele substituirá foo por bar . Aqui, estou substituindo AGE por si mesmo precedido por # . O \b corresponde a limites de palavras e exclui itens como ADAGE da correspondência. O $& é uma variável especial e significa "o que foi correspondido. Portanto, s/\bAGE\s/#$&/ substituirá AGE por #AGE .
  • s/$/\nAGE NIL/ : O $ corresponde ao final do registro. Portanto, substituí-lo por outra coisa será anexado ao final do registro. Este comando anexa AGE NIL ao final do registro correspondente.

Observe que todas as operações aqui diferenciam maiúsculas de minúsculas. Se você precisar de correspondência insensível a maiúsculas e minúsculas, use:

perl -00lpe 'if(/NAME#AAAA/i){s/\bAGE\s/#$&/i; s/$/\nAGE NIL/i;}' file
    
por 19.04.2016 / 16:57