Como substituir o texto entre dois marcadores em um arquivo por uma seção de texto de outro arquivo?

8

Digamos que eu tenha um bloco de texto no ~/.bashrc:

#~/.bashrc
# ...some commands...

# aliases
alias suicide='sudo rm -rf /'
# end aliases

# other commands

Desejo substituir esse bloco de texto por outro texto contido entre dois marcadores em outro arquivo: stuff-to-place-in-bashrc.txt

# stuff-to-place-in-bashrc.txt
# ...stuff...

# aliases
alias ldir='ls * -d'
alias ithinklifeisworthliving='echo all good'
# end aliases

# ...more stuff...

eu tentei

 sed -ne 's/# aliases\s+\(.*\)\s+# end aliases/\1/' stuff-to-place-in-bashrc.txt

Mas eu estou realmente balançando no escuro aqui. Alguém poderia me ajudar?

  1. Como extraio o texto do stuff-to-place-in-bashrc.txt?

  2. Como substituo a outra seção ~/.bashrcpelo texto extraído da pergunta 1?

Editar

Obrigado pelas atualizações pessoal, aqueles querendo saber por que eu iria querer algo como isto:

permite atualizações escolhidas a dedo em arquivos de script sem substituir as adições feitas pelo usuário. útil para ambientes operacionais padrão compartilhados e atualizados com freqüência (como meu último trabalho na Tyro que codificou com XP).

enlouqueçam.

thenaglecode
fonte
Ver também texto Captura entre chaves em C preprocessed arquivo . Mude "chaves" com seus tokens de início e fim ( # aliasese # end aliases), e isso pode funcionar para você.

Respostas:

9

Ed é o editor padrão, porque você pode usá-lo para desenvolver scripts de edição e deixar que ele funcione, como você testou anteriormente, de forma interativa. Para arquivos pequenos como .bashrcou qualquer texto de código, ed é de alto desempenho porque lê o arquivo inteiro de uma só vez e trabalha com o buffer. Pelo mesmo motivo, você não deve usar ed para arquivos grandes, como arquivos de log.

Mas com um script ed, seu trabalho é feito rapidamente:

ed ~/.bashrc<<EOF
/^# aliases
+,/^# end aliases/-1d
-r !sed -n '/^# aliases/,/^# end aliases/p' stuff-to-place-in-bashrc.txt|grep -v '^#'
w
q
EOF

Uso scripts semelhantes para ajustar automaticamente os arquivos de configuração, como também .asoundrc em diferentes ambientes para os quais levo meu laptop.

O melhor documento sobre ed vem como uma simples página de manual do muito legal sistema PLAN9 . Traduzi -o para um documento postscript ed.ps. Se você estiver interessado no PLAN9 , verifique o 9front e o http://cat-v.org/, pois a versão original do bell labs ainda é mantida, mas possui um sistema de arquivos muito simples.

Uma palavra final sobre editor wars, emacs, vim e similares: regras acme!

ikrabbe
fonte
Obrigado pela resposta, funcionou, mas não tenho certeza qual é a sintaxe. Ele usa regex ou algo mais específico para ed? Parece que há vim como comandos ( w, q)
thenaglecode
Ele usa expressões regulares ( /^# aliases, e /^# end aliases/), e os outros comandos são Vi / Ed. Consulte, por exemplo, vimhelp.appspot.com/cmdline.txt.html#%3Arange for +, /^# end aliases/.
Muru
1
veja info Edno seu sistema (espero). Não sei por que as distribuições modernas de linux não instalam este editor legal. weq são comandos de gravação e saída. E ed funciona muito semelhante ao sed com expressões regulares. Há uma razão pela qual os nomes soam assim. d significa excluir as linhas endereçadas, -r lê na linha anterior os resultados do !comando a seguir. Eu reduzo os nomes dos arquivos na edição, pois estou com preguiça de digitar esta manhã.
ikrabbe
1
@thenaglecode ver minha última edição. Eu tive que testar isso antes de postar.
ikrabbe
1
@thenaglecode A única e realmente boa página sobre ed que eu sempre precisei foi a página ed (1) do plan9: man.cat-v.org/plan_9/1/ed. Posso enviar uma versão postscript, se você quiser. Como estamos falando apenas do plan9, consulte o editor da acme também. Se você se acostumar com isso, nunca usará outra coisa. É claro que é melhor usar um sistema plan9, por exemplo, como uma máquina virtual dentro da sua caixa Linux, mas a porta p9p para unix também é ótima. (Há pequenas diferenças entre plan9 ed e GNU ed!)
ikrabbe
2
set /^\#aliases/  /^\#end\ aliases/
sed -ne"$1,$2"'s/\\\{0,1\}/&&/gp' <stuff_to_place...rc |
sed -e"$1,$2c\" -f- ./infile >./outfile

Se você deseja editar o arquivo no local, edé uma solução muito boa. Se você deseja editá-lo in-stream, use sed. Evite sed -i.

mikeserv
fonte
0

Claro, você pode fazer isso edsozinho, sem a necessidade de ferramentas adicionais:

ed -s stuff_to_place.txt<<\IN
1,/# aliases/d
/# end aliases/,$d
,d
.r /home/username/.bashrc
/# aliases/x
.t.
.,/# end aliases/-d
,p
q
IN

se você estiver satisfeito com o resultado, substitua ,ppor w /home/username/.bashrcpara escrever as alterações em ~/.bashrc(observe o caminho completo usado com re w; você pode simplesmente usá- .bashrclo se estiver dentro cwd).
Como isso funciona: primeiro dexcluímos as linhas desnecessárias stuff_to_place.txt. Em seguida, excluímos os restantes (os aliases) com ,d. O buffer de texto agora está vazio enquanto o buffer de corte contém as linhas que queremos. Em seguida, read o conteúdo .bashrcpara o buffer de texto, coloque o conteúdo do buffer de corte ( x) para depois da /# aliases/linha, duplicar a última linha que foi colado ( .t.), em seguida, apagar a partir da linha duplicada até, mas não incluindo /# end aliases/e, finalmente, print ou writo mudanças e quit.

don_crissti
fonte