Três comandos sed
diferentes:
sed '$!N;s/"[^"]*"\n<[^>]*>/other characters /;P;D'
sed -e :n -e '$!N;s/"[^"]*"\n<[^>]*>/other characters /;tn'
sed -e :n -e '$!N;/"$/{$!bn' -e '};s/"[^"]*"\n<[^>]*>/other characters /g'
Todos os três compilam o comando básico s///
ubstitution:
s/"[^"]*"\n<[^>]*>/other characters /
Eles também tentam tomar cuidado ao manipular a última linha, pois sed
s tende a diferir em sua saída nos casos de borda. Esse é o significado de $!
, que é um endereço que corresponde a todas as linhas que são !
e não o $
por último.
Eles também usam o comando N
ext para anexar a próxima linha de entrada ao espaço padrão seguindo um caractere \n
ewline. Qualquer um que tenha estado sed
ing por um tempo terá aprendido a confiar no caractere \n
ewline - porque a única maneira de obter um é explicitamente colocá-lo lá.
Todos os três tentam ler o mínimo possível de informações antes de executar uma ação - sed
age assim que pode e não precisa ler em um arquivo de entrada inteiro antes de fazer isso.
Apesar de todos fazerem N
, todos os três diferem em seus métodos de recursão.
Primeiro Comando
O primeiro comando emprega um loop N;P;D
muito simples. Esses três comandos são embutidos em qualquer sed
compatível com POSIX e se complementam bem.
-
N
- como já mencionado, acrescenta a linha de entradaN
ext ao espaço padrão seguindo um delimitador% e_line% ewline inserido. -
\n
- comoP
; elep
rints pattern-space - mas apenas até o primeiro caractereP
ewline. E assim, dada a seguinte entrada / comando:-
\n
-
-
printf %s\n one two | sed '$!N;P;d'
sed
rints apenas um . No entanto, com ... -
P
- comoD
; eled
elimina o espaço padrão e inicia outro ciclo de linha. Ao contrário deD
,d
exclui apenas até a primeiraD
ewline no padrão de espaço. Se houver mais no espaço padrão seguindo o caractere\n
ewline,\n
iniciará o próximo ciclo de linha com o que resta. Se osed
no exemplo anterior fosse substituído pord
, por exemplo,D
seriased
rint ambos um e dois .
Este comando recursa apenas para linhas que não correspondem à declaração P
ubstitution. Como o s///
ubstitution remove o s///
ewline adicionado com \n
, nunca há nada restante quando N
sed
elimina o espaço padrão.
Testes podem ser feitos para aplicar os D
e / ou P
seletivamente, mas existem outros comandos que se encaixam melhor nessa estratégia. Como a recursão é implementada para lidar com linhas consecutivas que correspondem apenas a parte da regra de substituição, sequências consecutivas de linhas correspondentes a ambas terminam da D
ubstitution não funcionam bem. :
Dada essa entrada:
first "line"
<second>"line"
<second>"line"
<second>line and so on
... imprime ...
first other characters "line"
<second>other characters line and so on
No entanto, ele lida com
first "line"
second "line"
<second>line
... muito bem.
Segundo comando
Este comando é muito semelhante ao terceiro. Ambos empregam um rótulo s///
ranch / :b
est (como também é demonstrado na resposta de Joeseph R. aqui ) e recorre a ele dadas certas condições.
-
Os scripts
t
- portable-e :n -e
delimitarão uma definição de rótulosed
com uma instrução:
eww ou uma nova instrução\n
xecução inline.-
-e
- define um rótulo chamado:n
. Isso pode ser retornado a qualquer momento comn
oubn
.
-
-
tn
- o comandotn
est retorna a um rótulo especificado (ou, se nenhum for fornecido, encerra o script para o ciclo de linha atual) se houvert
ubstitution desde o rótulo foi definido ou desde que foi chamado pela última vezs///
ests bem-sucedido.
Neste comando, a recursão ocorre para as linhas correspondentes. Se t
substituir com êxito o padrão por outros caracteres , sed
retornará ao rótulo sed
e tentará novamente. Se uma :n
ubstitution não for executada s///
autoprints padrão-espaço e iniciar o próximo ciclo de linha.
Isso tende a lidar com sequências consecutivas melhor. Onde o último falhou, isso imprime:
first other characters other characters other characters line and so on
Terceiro Comando
Como mencionado, a lógica aqui é muito semelhante à anterior, mas o teste é mais explícito.
-
sed
- este é o teste de/"$/bn
. Como o comandosed
ranch é uma função desse endereço,b
será apenassed
ranch de volta parab
depois que um:n
ewline for anexado e o espaço padrão ainda terminar com\n
aspas duplas .
Existe tão pouco quanto possível entre "
e N
- dessa forma, b
pode coletar exatamente o máximo de entradas necessárias para garantir que a linha a seguir não corresponda à sua regra. O sed
ubstitution difere aqui, pois emprega o sinalizador s///
lobal - e, portanto, fará todas as substituições necessárias de uma só vez. Dada a entrada idêntica, este comando é enviado de forma idêntica ao último.