Três sed
comandos 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 se baseiam no s///
comando básico de ubstitution:
s/"[^"]*"\n<[^>]*>/other characters /
Todos eles também tentam tomar cuidado no manuseio da última linha, pois os sed
s tendem a diferir em sua saída em casos extremos. Esse é o significado de $!
um endereço que corresponde a todas as linhas que !
não são as $
últimas.
Todos também usam o N
comando ext para anexar a próxima linha de entrada ao espaço do padrão após um \n
caractere ewline. Qualquer pessoa que esteja sed
há algum tempo aprenderá a confiar no \n
personagem ewline - porque a única maneira de conseguir um é explicitamente colocá-lo lá.
Todos os três tentam ler o mínimo possível de informações antes de tomar uma ação - sed
agem o mais rápido possível e não precisam ler um arquivo de entrada inteiro antes de fazê-lo.
Embora façam tudo N
, todos os três diferem em seus métodos de recursão.
Primeiro Comando
O primeiro comando emprega um N;P;D
loop muito simples . Esses três comandos são integrados a qualquer POSIX compatível sed
e se complementam muito bem.
N
- como já mencionado, anexa a N
linha de entrada ext ao espaço padrão após um \n
delimitador de linha de linha inserido .
P
- como p
; ele P
cria espaço no padrão - mas apenas até o primeiro \n
caractere ewline que ocorre . E assim, dada a seguinte entrada / comando:
printf %s\\n one two | sed '$!N;P;d'
sed
P
Rints apenas um . No entanto, com ...
D
- como d
; ele D
elimina o espaço padrão e inicia outro ciclo de linha. Ao contrário d
, D
exclui apenas até a primeira linha de \n
ew que ocorre no espaço do padrão. Se houver mais espaço no padrão após o \n
caractere ewline, sed
inicia o próximo ciclo de linha com o que resta. Se o d
no exemplo anterior foram substituídos com um D
, por exemplo, sed
seria P
Rint tanto um e dois .
Este comando ocorre apenas para linhas que não correspondem à s///
instrução ubstitution. Como a ubstitution s///
remove o \n
ewline adicionado com N
, nunca resta nada quando se sed
D
elimina o espaço do padrão.
Poderiam ser feitos testes para aplicar o P
e / ou D
seletivamente, mas existem outros comandos que se encaixam melhor nessa estratégia. Como a recursão é implementada para manipular linhas consecutivas que correspondem apenas a parte da regra de substituição, sequências consecutivas de linhas correspondentes às duas extremidades da s///
substituição não funcionam bem .:
Dada esta 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, lida com
first "line"
second "line"
<second>line
...bem.
Segundo comando
Este comando é muito semelhante ao terceiro. Ambos empregam um rótulo de :b
fazenda / t
est (como também é demonstrado na resposta de Joeseph R. aqui ) e retornam a ele sob determinadas condições.
-e :n -e
- sed
scripts portáteis delimitarão uma :
definição de rótulo com uma linha de \n
ew ou uma nova -e
instrução de xecution em linha .
:n
- define um rótulo chamado n
. Isso pode ser retornado a qualquer momento com bn
ou tn
.
tn
- o t
comando est retorna para um rótulo especificado (ou, se nenhum for fornecido, sai do script para o ciclo de linha atual) se houver alguma s///
substituição desde que o rótulo foi definido ou desde a última vez que foi chamado t
ests com êxito.
Neste comando, a recursão ocorre para as linhas correspondentes. Se sed
substituir com êxito o padrão por outros caracteres , sed
retornará ao :n
rótulo e tentará novamente. Se uma s///
substituição não for executada, o sed
espaço de padrão é impresso automaticamente e inicia o próximo ciclo de linha.
Isso tende a lidar melhor com seqüências consecutivas. 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.
/"$/bn
- este é sed
o teste. Como o b
comando ranch é uma função desse endereço, sed
ele b
retornará somente :n
depois que um \n
ewline for acrescentado e o espaço do padrão ainda terminar com "
aspas duplas.
Há o mínimo possível entre N
e b
quanto possível - dessa maneira, é sed
possível reunir rapidamente, exatamente, o máximo de entrada necessário para garantir que a linha a seguir não corresponda à sua regra. A s///
ubstituição difere aqui porque emprega a g
bandeira global - e, portanto, fará todas as substituições necessárias de uma só vez. Dada entrada idêntica, este comando é idêntico ao último.
\n
declaração ewline que você faz é por que eu pergunto. as pessoas raramente perguntam se podem fazer os//\n/
que você pode fazer com o GNUsed
, embora a maioria dos outrossed
rejeite essa fuga no lado direito. ainda assim, a\n
fuga funcionará à esquerda em qualquer POSIXsed
e você poderá traduzi-las de forma portável, comoy/c/\n/
se ela tivesse o mesmo efeitos/c/\n/g
e, portanto, nem sempre é tão útil.