A documentação do POSIX sed disse:
Uma função pode ser precedida por um ou mais '!' caracteres, caso em que a função será aplicada se os endereços não selecionarem o espaço do padrão. Zero ou mais caracteres <blank> serão aceitos antes do primeiro '!' personagem. Não é especificado se os caracteres <blank> podem seguir um '!' caractere e aplicativos conformes não devem seguir um '!' caractere com caracteres <blank>.
Assim, com qualquer POSIX sed, podemos:
sed -e '/pattern/!d' file
É o mesmo que escrever:
sed -e '/pattern/!!d' file
E !!!d
e n
de exclamação marcas ainda estão ficar bem (testado com três sed
versão de herança Toolchest ). Não vejo nenhum benefício entre vários em vez de uma exclamação.
Por que a especificação permitiu essa sintaxe e como é útil na aplicação no mundo real?
Parece que o GNU sed não é compatível neste caso, ele irá reclamar se usarmos várias exclamações:
$ sed -e '/pattern/!!d' file
sed: -e expression #1, char 11: multiple `!'s
!
atua como uma alternância,/pattern/!!
é o mesmo que/pattern/
e/pattern/!!!
é o mesmo que/pattern/!
. No FreeBSD, múltiplos!
são iguais a um único.sed
scripts podem ser gerados . Dado um POSIXsed
, deve ser uma questão realmente simples escrever a escrita de umsed
script. Portanto, se você tiver algum gatilho para algum caso que marcará um endereço que!
não seja digno de sua ação, você poderá acioná-lo várias vezes para o mesmo e ainda assim obter os mesmos resultados.sed
s não são.Respostas:
sed
A API é primitiva - e isso é por design. Pelo menos, ele permaneceu primitivo por design - se ele foi concebido primitivamente desde o início, não posso dizer. Na maioria dos casos, a escrita de umsed
script que, quando executado, produzirá outrosed
script, é realmente uma questão simples.sed
é frequentemente aplicado dessa maneira por pré-processadores de macro comom4
e / oumake
.(O que se segue é um caso de uso altamente hipotético: é um problema projetado para se adequar a uma solução. Se parecer um esticamento para você, provavelmente é porque é, mas isso não necessariamente o torna menos válido.)
Considere o seguinte arquivo de entrada:
Se desejássemos escrever um
sed
script que anexasse a palavra -case à cauda de cada palavra apropriada no arquivo de entrada acima, apenas se ele pudesse ser encontrado em uma linha no contexto apropriado , e desejássemos fazê-lo da maneira mais eficiente possível ( como deve ser nosso objetivo, por exemplo, durante uma operação de compilação) , devemos preferir evitar aplicar o máximo de/
regexp/
s.Uma coisa que podemos fazer é pré-editar o arquivo em nosso sistema agora e nunca ligar
sed
durante a compilação. Mas se alguma dessas palavras no arquivo deve ou não ser incluída com base nas configurações locais e / ou nas opções de tempo de compilação, isso provavelmente não seria uma alternativa desejável.Outra coisa que podemos fazer é processar o arquivo agora contra regexps. Podemos produzir - e incluir em nossa compilação - um
sed
script que pode aplicar edições de acordo com o número da linha - que normalmente é uma rota muito mais eficiente a longo prazo.Por exemplo:
... que grava a saída na forma de um
sed
script e que se parece com ...Quando essa saída é salva em um arquivo de texto executável na minha máquina chamado
./bang.sed
e executado como./bang.sed ./infile
, a saída é:Agora você pode me perguntar ... Por que eu iria querer fazer isso? Por que eu não apenas ancorava
grep
os fósforos? Quem usa o estojo de camelo, afinal? E para cada pergunta que eu só podia responder, não faço ideia ... porque não faço. Antes de ler esta pergunta, eu nunca havia notado pessoalmente o multi-! requisito de análise nas especificações - acho que é uma captura bem legal.O multi-! coisa que imediatamente faz sentido para mim, embora - a maior parte da
sed
especificação é voltado para simplesmente analisados e simplesmente geradossed
scripts. Você provavelmente encontrará os\n
delimitadores de linha eletrônica necessários para[wr:bt{]
fazer muito mais sentido nesse contexto, e se você mantiver essa ideia em mente, poderá entender melhor alguns outros aspectos da especificação - (como:
não aceitar endereços eq
se recusar a aceite mais de 1) .No exemplo acima, eu escrevo uma certa forma de
sed
script que só pode nunca ser lido uma vez. Se você observar bem, poderá perceber que, à medida quesed
lê o arquivo de edição, ele progride de um bloco de comando para o próximo - ele nunca se afasta ou completa seu script de edição até que termine completamente com seu arquivo de edição.Eu considero isso multi-! endereços podem ser mais úteis nesse contexto do que em alguns outros, mas, honestamente, não consigo pensar em um único caso em que eu possa tê-lo usado muito bem - e
sed
muito. Também acho digno de nota quesed
ambos os GNU / BSD não conseguem lidar com isso conforme especificado - esse provavelmente não é um aspecto da especificação que é muito requisitado e, portanto, se uma implementação a ignora, duvido muito seriamente que seus bugs @ box sofrerão terrivelmente como resultado.Dito isso, a falha em lidar com isso como especificado é um bug para qualquer implementação que pretenda conformidade, e por isso acho que enviar um email para as caixas de desenvolvimento relevantes é necessário aqui, e pretendo fazê-lo, se não o fizer.
fonte
!
será removido na próxima especificação , o que está acontecendo aqui!