Eu tenho que substituir um grande bloco de texto (código de script de shell) em um arquivo por outro bloco de texto.
Estou impressionado com o Como posso usar o sed para substituir uma string de várias linhas? respondidas por antak e Multi-line replace respondidas por Bruce Ediger
Mas tenho alguns problemas em usá-los.
O Antak já mencionou em sua resposta que o streaming de arquivo inteiro (
1h;2,$H;$!d;g;
) para o buffer não é aconselhável para arquivos grandes, porque sobrecarrega a memória.Eu sei que
sed
pode ser usado com o recurso de bloco para preservar o texto fora do bloco inalterado. Eu quero usar esse recurso. Mas se eu usar,sed -i '/marker1/,/marker2/s/.*/new text (code)/' filename
ele irá inserir novo texto (código) repetidamente para cada fluxo. Portanto, eu tenho que fazer o bloco visual como um fluxo, usando algo semelhante ao sugerido por antak anteriormente, mas para o bloco (não para o arquivo inteiro).
Conforme mencionado por Bruce Ediger, é possível tentar o recurso de acréscimo
ex
que começa coma
final com.
(ponto), mas meu novo texto (código) contém linhas que começam com ponto, que pode ser considerado como o ponto da sintaxe de acréscimo. Como posso usá-lo nesta situação?ex
'sdd
' number of lines 'pode excluir várias linhas, mas se eu tiver um bloco entre / marker1 / e / marker2 / com o número de linhas não fixas (variando) será substituído por um novo texto (código), como fazer isto ?
sed
ouex
comando funciona).r
o comando read file para copiar o texto de outro arquivo, se a origem do texto de substituição estiver em um arquivo.Respostas:
Eu sugiro usar o c comando hange (que é essencialmente um d elete juntamente com um um ppend, embora o acréscimo é aplicado somente para a última linha na faixa que é exatamente o que você quer aqui):
Aqui, usando
sed
a sintaxe do GNU para edição in-loco (-i
).c
Caso contrário, esse comando é padrão e portátil. O GNUsed
suporta:como uma extensão não padrão.
Os caracteres de nova linha e barra invertida devem ser escapados (com barra invertida) no texto de substituição.
fonte
sed
e para osex
mesmos. Muito obrigado.sed
como no caso daex
sintaxe sugerida por Bruce Ediger na substituição de várias linhas .r
comando discutido em outras respostas para essa pergunta. Não tenho certeza de como você usaria um documento aquised
.Usando o GNU sed
Para substituir linhas iniciando uma correspondência de linha
3
e continuando para uma linha correspondente5
aNew Code
:Para linhas no intervalo
/3/,/5/
, testamos para ver se a linha corresponde5
(o que significa que esta é a última linha do grupo) e, nesse caso, fazemos a substituição para inserirNew Code
. Se a substituição foi feita, ot
comando diz ao sed para pular para o final dos comandos (nesse caso,New Code
é impresso). Caso contrário, od
comando diz ao sed para excluir a linha.Todas as outras linhas são impressas normalmente.
Para alterar o arquivo no local, a
-i
opção pode ser usada:Usando awk
Para fazer o mesmo usando o awk:
O comando awk trata especialmente as linhas no intervalo
/3/,/5/
. Para linhas nesse intervalo, testamos para ver sef
é zero (ou seja, se!f
é verdade) e, se sim, imprimimosNew Code
e configuramosf
como 1 e depois pulamos o restante dos comandos e pulamos para anext
linha.Para linhas fora do intervalo
/3/,/5/
, nenhum salto é feito e1
faz com que a linha seja impressa. Em mais detalhes,1
é uma condição. Como1
não é zero, a condição é avaliada como verdadeira. Como nenhuma ação está associada à condição, é executada a ação padrão que é imprimir a linha. Assim,1
é uma abreviação para print-the-line.Para alterar um arquivo, a
-i inplace
opção pode ser usada com o GNUawk
4.1 ou superior:fonte
awk
, você poderia explicar pouco suaawk
expressãosed '/3/,/4/d;/5/cNew Code'
awk '/5/{print "New Code"}/3/,/5/{next}1'
Com base na discussão acima, eu venho com uma solução usando
ex
O exposto acima
Obrigado g-man por me informar sobre o comando change e dar esclarecimentos sobre o dot. Ambos
sed
eex
share sintaxe quase semelhante para o comando de mudança (também para comando de exclusão, o comando de acréscimo, etc).fonte