sed
é primitiva - e isso é por design. Pelo menos, ele permaneceu primitivo por design - quer tenha sido projetado primitivamente no início, não posso dizer. Na maioria dos casos, a escrita de um script sed
que, quando executado, produzirá outro sed
script é uma questão simples. sed
é frequentemente aplicado dessa forma por pré-processadores de macro, como m4
e / ou make
.
(O que se segue é um caso de uso altamente hipotético: trata-se de um problema projetado para se adequar a uma solução. Se parece um trecho para você, provavelmente é porque é, mas isso não necessariamente é menos válido.)
Considere o seguinte arquivo de entrada:
cat <<"" >./infile
camel
cat dog camel
dog cat
switch
upper
lower
Se quiséssemos escrever um script sed
que acrescentaria a palavra -case ao final de cada palavra apropriada no arquivo de entrada acima somente se pudesse ser encontrado em uma linha em contexto apropriado , e nós desejamos fazê-lo tão eficientemente quanto possível (como deveria ser nosso objetivo, por exemplo, durante uma operação de compilação) então deve preferir evitar aplicar o /
regexp /
s o máximo possível.
Uma coisa que podemos fazer é pré-editar o arquivo em nosso sistema agora, e nunca chamar sed
durante a compilação. Mas se qualquer uma 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, fazer isso provavelmente não seria uma alternativa desejável.
Outra coisa que podemos fazer é processar o arquivo agora contra regexps. Nós podemos produzir - e incluir em nossa compilação - um script sed
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:
n=$(printf '\\n\t')
grep -En 'camel|upper|lower' <infile |
sed " 1i${n%?}#!/usr/heirloom/bin/posix2001/sed -nf
s/[^:]*/:&$n&!n;&!b&$n&/;s/://2;\$a${n%?}q"'
s/ *cat/!/g;s/ *dog/!/g
s| *\([cul][^ ]*\).*|s/.*/-case/p|'
... que grava a saída na forma de um script sed
e que se parece com ...
#!/usr/heirloom/bin/posix2001/sed -nf
:1
1!n;1!b1
1s/.*/camel-case/p
:2
2!n;2!b2
2!!s/.*/camel-case/p
:5
5!n;5!b5
5s/.*/upper-case/p
:6
6!n;6!b6
6s/.*/lower-case/p
q
Quando essa saída é salva em um arquivo de texto executável em minha máquina chamada ./bang.sed
e executada como ./bang.sed ./infile
, a saída é:
camel-case
upper-case
lower-case
Agora você pode me perguntar ... Por que eu iria querer fazer isso? Por que eu não apenas ancoraria as combinações de grep
? Quem usa o caso do camelo mesmo assim? E para cada pergunta eu só poderia responder, eu não tenho idéia ... porque eu não sei. Antes de ler esta pergunta, eu nunca tinha notado pessoalmente o requisito de análise multi -! na especificação - eu acho que é uma boa idéia.
O multi -! coisa fez imediatamente faz sentido para mim - muito da especificação sed
é voltada para simplesmente analisada e simplesmente gerada sed
scripts. Você provavelmente achará que os delimitadores \n
ewline necessários para [wr:bt{]
fazem muito mais sentido nesse contexto, e se você mantiver essa idéia em mente, poderá ter uma melhor noção de alguns outros aspectos da especificação - ( como :
sem aceitar endereços e q
se recusando a aceitar mais do que 1) .
No exemplo acima eu escrevo uma certa forma de sed
script que só pode ever ser lida uma vez. Se você olhar com atenção para isso, poderá notar que, como sed
lê o arquivo de edição, ele progride de um bloco de comando para o seguinte - ele nunca separa ou conclui seu script de edição até que seja completamente finalizado. arquivo.
Eu considero que os endereços multi -! podem ser mais úteis nesse contexto do que em outros, mas, na honestidade, não consigo pensar em um único caso em que eu possa ter dito para muito bom uso - e eu sed
muito. Eu também acho que é digno de nota que GNU / BSD sed
s não conseguem lidar com isso como especificado - este provavelmente não é um aspecto da especificação que é muito demandada, então se uma implementação negligencia, eu duvido seriamente que eles > Bugs @ caixa irá sofrer terrivelmente como resultado.
Dito isto, a falha em lidar com isso como é um bug para qualquer implementação que pretenda ser compatível, então acho que filmar um e-mail para os dev boxes relevantes é chamado aqui, e eu pretendo fazê-lo se você não fizer isso.