Suponha que reformulamos os requisitos como este:
- Temos um arquivo de parágrafos, que são regiões de linhas consecutivas não vazias, separadas por uma ou mais linhas vazias.
-
Sempre que "padrão" ocorre dentro de um parágrafo, gostaríamos que essa linha iniciasse um novo parágrafo, exceto quando "padrão" ocorre na primeira linha de um parágrafo.
-
Além disso, não nos importamos em normalizar o arquivo para que exista exatamente uma linha vazia entre os parágrafos, e nenhuma linha vazia no início ou no final. *
Se esses requisitos forem aceitáveis, podemos aproveitar o modo de parágrafo do Awk (ativado um valor vazio em RS
):
awk 'BEGIN { RS=""; FS="\n" }
{ print sep $1;
for (i = 2; i <= NF; i++)
{ if ($i ~ /pat/) print ""; print $i }
sep=FS }'
No modo de parágrafo, os registros são parágrafos. Como estamos usando \n
como FS
, os campos $1, $2, ... $NF
correspondem a linhas de parágrafos. Por exemplo, se NF
for 5, então estamos lidando com um parágrafo de cinco linhas. As novas linhas de separação de parágrafo são removidas e cada registro $0
contém apenas as novas linhas internas entre as linhas, e a divisão de campo é feita nelas.
Um parágrafo tem pelo menos uma linha, porque os parágrafos não podem estar vazios: um parágrafo vazio se parece com duas novas linhas consecutivas que fazem parte do mesmo parágrafo que separa a sequência.
Portanto, sem verificar se NF
é pelo menos 1, apenas imprimimos a linha do primeiro parágrafo com print sep $1
. A primeira vez, sep
está vazia, portanto, não tem importância; mas depois do primeiro parágrafo, definimos sep
para uma nova linha, para que o próximo print sep $1
gere a separação de parágrafos.
Após imprimir a primeira linha, iteramos as linhas restantes, se houver, e as imprimimos. Aqui, nós verificamos se cada linha corresponde ao padrão. Se assim for, emitimos uma linha extra em branco antes de imprimi-lo.