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 sedeu 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 Ycriar a primeira linha e digitar
:2,$g/<C-r>0/dpara 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 myfileidê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>0muito 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 \Ve 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'
sedtambé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 sedtodo 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'