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 chamadaprint
.-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 aNAME#AAAA
. -
s/\bAGE\s/#$&/
: Os/foo/bar/
é o operador de substituição. Ele substituiráfoo
porbar
. Aqui, estou substituindoAGE
por si mesmo precedido por#
. O\b
corresponde a limites de palavras e exclui itens comoADAGE
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 anexaAGE 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