Substituição multilinha no shell

Substituição multilinha no shell

Eu tenho os seguintes pedaços de texto em um arquivo de texto:

* Exported from Foo *

Title and Section

e outro

* Exported from Foo *

Other Title and Other Section

Eu preciso substituir isso por

# Title and Section

e

# Other Title and Other Section

Agora posso fazer isso com:

echo "$(grep -A 2 "Exported from Foo" ../tmp/data/${nospacefile} | grep -v "Exported from Foo" | grep -v -- -- | tr -d '\r' | grep -v -e '^[[:space:]]*$' | sed -e 's/^[ \t]*//')" | while read -r title; do sed -i -e "s/^\([[:blank:]]*\)$title/\# $title/g" ../tmp/data/${nospacefile}; done

No entanto, a string "Título e Seção" ou "Outro Título e Outra Seção" também aparece em locais que não desejo substituir. Só quero que ele seja substituído se aparecer após a linha Exportado e uma linha em branco.

Qual é a melhor construção de shell disponível para eu fazer isso? Estou mais do que feliz em enviar stdout para perl, python, qualquer que seja.

Responder1

Você pode tentar ed(1)editar a terceira linha começando * Exported from Foo *independentemente de a segunda linha estar vazia ou não.

Para apenas imprimir a saída como stdoutsed

printf '%s\n' 'g/^\* Exported from Foo \*$/+2s/^/# /' ,p Q | ed -s file.txt 

Isso apenas imprime a saída para stdouteditar o arquivo no local.

printf '%s\n' 'g/^\* Exported from Foo \*$/+2s/^/# /' w | ed -s file.txt 

Para usar um edscript que apenas imprima a saída emstdout

cat script.ed

Saída

g/^\* Exported from Foo \*$/+2s/^/# /
,p
Q

O script que edita o arquivoin-place

g/^\* Exported from Foo \*$/+2s/^/# /
w
q

Agora você pode fazer

ed -s file.txt < script.ed

informação relacionada