Substituir uma expressão regular no vim por uma saída produzida por um comando do console com a expressão como argumento?

Substituir uma expressão regular no vim por uma saída produzida por um comando do console com a expressão como argumento?

digamos que eu tenha um arquivo com o seguinte conteúdo:

Este é um _arquivo_ que contém algumas palavras-chave _especiais_, que eu _gostaria_ de substituir.

Posso fazer uma pesquisa e substituir as palavras-chave específicas por "%s/_*_/something", mas gostaria que "something" fosse uma saída de um comando externo. Isso é possível no vim ou preciso ativá-lo?

Responder1

Sim você pode. Ver :help sub-replace-special; the \=permite que você substitua por uma expressão do Vim. E system()pode executar um comando externo e retornar sua saída. Veja meu exemplo trivial com hostname. Observe que tive que usar substitute()para me livrar dos caracteres de nova linha finais na saída.

:%s/_[^_]*_/\=substitute(system('hostname'),'\n','','g')/g

PS: Também corrigi seu padrão regexp para corresponder ao seu exemplo.

Responder2

Na resposta do Ingos, que me ajudou muito, não vejo como fazer referência a um subpadrão da partida e usá-lo como argumento para o comando shell ("produzido por um comando de console com a expressão como argumento").

No meu caso, eu tinha linhas de log no seguinte formato: [<unix timestamp>] <message>, ou seja [1406844000] foobar. Eu queria anexá-los com a hora em uma forma legível por humanos.

O seguinte comando vim corresponde ao carimbo de data/hora (subcorrespondência 1) e à mensagem (o restante, subcorrespondência 2) e precede a string de hora do comando de data:

:% s/^\[\(\d\+\)\] \(.*\)$/\=substitute(system('date -d @'.submatch(1)),'\n', '', 'g').': ['.submatch(1).'] '.submatch(2)/

[1406844000] foobarconsegue Fr 1. Aug 00:00:00 CEST 2014: [1406844000] foobar.

HTH

Responder3

Para substituição base64 em um arquivo ldiff:

:%s/:: \(.*\)$/\=substitute(': ' . system('echo '.submatch(1).'|base64 -d'),'\n','','g')/

informação relacionada