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-ea 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áfooporbar. Aqui, estou substituindoAGEpor si mesmo precedido por#. O\bcorresponde a limites de palavras e exclui itens comoADAGEda correspondência. O$&é uma variável especial e significa "o que foi correspondido. Portanto,s/\bAGE\s/#$&/substituiráAGEpor#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 NILao 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