Linhas duplicadas começando com "x", substituindo "x" na duplicata por "y"?

9

Eu tenho um arquivo com o seguinte padrão:

foo 111
baz
foo 222
baz
foo 333
baz

que precisa ser transformado em

foo 111
bar 111
baz
foo 222
bar 222
baz
foo 333
bar 333
baz

Portanto, duplique todas as linhas que começam com fooe mude apenas foona duplicata, mas deixe o restante da linha (que difere em cada caso) intacto. Como fazer isso?

LB7979
fonte
Se você não está confinado a uma regexp, uma macro funciona perfeitamente. Realmente não importa muito em casos simples como esse, mas se você tiver algo um pouco mais complicado, é uma alternativa muito válida.
precisa saber é o seguinte

Respostas:

19

Aqui está:

:g/foo/t.|s//bar

Decomposição:

:g/foo/    " start a global command applied on all lines matching 'foo'
t.         " duplicate the current line (the cursor is now on the new line)
|          " chain a new command
s//bar     " substitute the last searched element with 'bar'

Como o gcomando atualizará o padrão de pesquisa, você poderá omitir o padrão para substituir no comando substitute. (ref:, :h :gprocure search pattern).


Versão antiga:

:g/foo/norm! yyp:s/foo/bar^M

Decomposição:

:g            start a global command
/foo/         apply only on lines having 'foo'
norm!         execute a normal command
yyp           duplicate the line
:s//bar       replace foo with bar on the line (the duplicated one)
^M            add enter to execute the substitution

Para inserir a ^Mimprensa Ctrl+ve enter.

Nota : Originalmente, eu vim com a versão "mais antiga" antes de aprender sobre o tcomando. Vou deixar, mas não vou recomendar o uso. O primeiro é mais limpo e direto.

nobe4
fonte
Resolvida, a 'versão mais simples' funcionou perfeitamente. A primeira versão no entanto, resultou na linha duplicada ainda começando com foo....
LB7979
estranho, você entrou ^Mcomo eu expliquei?
nobe4
Meu mal, não leu muito bem. A primeira solução também funciona!
LB7979
Não sei por que você se incomoda em incluir a versão complicada. A versão mais simples é ... mais simples. ;) (Sem mencionar a compatibilidade com POSIX.) Por que não colocá-lo em primeiro lugar?
Curinga
11
Inicialmente, criei a primeira versão, que era mais natural para mim, porque na época eu não tinha conhecimento te, em seguida, adicionei a segunda. Vou mudar a ordem, você está certo. Que tal o primeiro sendo POSIX?
nobe4
1

Eu faço coisas assim o tempo todo e apenas faço algo assim %s/^foo \(.*\)/foo \1\rbar \1/(parcialmente porque eu também faço muitas tarefas semelhantes que não podem ser transformadas em algo inteligente usando uma função de cópia e que agora \(.*\)faz parte da minha memória muscular).

Eu suspeito que não seja compatível com POSIX (não funciona em outros clones vi), mas usar ^M( C-VReturn) em vez de \rparece funcionar na maioria dos outros clones vi.

Random832
fonte