Eu estava olhando para essa pergunta e depois me perguntei como poderia implementar minha resposta que usa
sed
usando puramente
POSIX
ex
.
O truque é que, enquanto sed
eu posso comparar o espaço de espera com o espaço do padrão para ver se eles são exatamente equivalentes (com
G;/^\(.*\)\n\1$/{do something}
), não conheço nenhuma maneira de fazer esse teste ex
.
Eu sei que no Vim eu poderia Y
criar a primeira linha e digitar
:2,$g/<C-r>0/d
para quase fazer o que estou especificando - mas se a primeira linha contiver algo além de um texto alfanumérico muito simples, isso se tornará arriscado, pois a linha está sendo inserida como uma
expressão regular , não apenas uma sequência para comparação. (E se a primeira linha contiver uma barra, o restante da linha será interpretado como um comando!)
Portanto, se eu quiser excluir todas as linhas myfile
idênticas à primeira linha - mas não excluir a primeira linha - como eu poderia fazer isso usando ex
? Por falar nisso, como eu poderia fazer isso usando vi
?
Existe uma maneira POSIX de excluir uma linha se ela corresponder exatamente a outra linha?
Talvez algo como esta sintaxe imaginária:
:2,$g/**lines equal to "0**/d
<C-r>0
muito boa. Não tenho certeza de que você poderia fazer melhor apenas com os comandos Ex, porque você precisa proteger caracteres especiais. Sem a restrição compatível com POSIX, acho que você usaria a opção muito nomagic \V
e protegeria a barra invertida (porque mantém seu significado especial mesmo \V
) com a escape()
função cujo segundo argumento é uma string que contém todos os caracteres dos quais você deseja escapar / proteger .
:execute '2,$g/\V' . escape(getline(1), '\/') . '/d'
Ou você poderia usar outro caractere para o delimitador de padrão como um ponto e vírgula. Nesse caso, você não precisaria proteger uma barra no padrão. Isso daria algo como::execute '2,$g;\V' . escape(getline(1), '\') . ';d'
sed
também muito boa. Com o Vim, você frequentemente delega certas tarefas especiais para outros programas e sed
é provavelmente um bom exemplo disso. A propósito, você não precisa executar sed
todo o seu buffer. Se você deseja executá-lo apenas em uma parte do buffer, pode dar um intervalo. Por exemplo, se você deseja filtrar apenas as linhas entre 50 e 100, você pode digitar: :50,100!<your sed command>
.
:execute '2,$g/\V' . escape(getline(1), '\') . '/d'