O buffer h old é bom para armazenar uma linha (ou grupo de linhas) até que algum teste posterior seja verdade. Em outras palavras, é bom para lidar com sequências de dados que você quer sequencial, mas não são ainda seqüenciais - porque permite que você as coloque juntas. Mas também requer muitas cópias entre os dois buffers. Isso não é tão ruim se você está construindo uma série de linhas com comandos H old - apenas acrescentar - mas toda vez que você e x mudam os buffers, você copia o todo de um para o outro e vice-versa.
Quando você está trabalhando com uma série de linhas que já são sequenciais e deseja removê-las com base no contexto, o melhor caminho a seguir é com
look- à frente - ao contrário da aparência do por trás . cuonglm faz isso para a segunda metade de sua resposta já - mas você pode usar essa lógica para qualquer forma.
sed '$!N;/\nage.*: 10/P;D' <infile >outfile
Veja, isso anexará a linha de entrada h ext após um delimitador de linha de código N incorporado ao espaço de padrão atual em cada linha que for \n e não ! da última. Em seguida, ele verifica se a linha que acabou de ser extraída corresponde a um padrão e, em caso afirmativo, que $ rints somente até o primeiro P ewline no espaço de padrão - apenas a linha anterior. Por último, \n elimina o primeiro D ewline no espaço padrão e inicia o ciclo novamente. Assim, ao longo do arquivo, você mantém uma aparência de uma linha: adiante sem trocar buffers desnecessariamente.
Se eu alterar o comando apenas um pouco, você poderá ver especificamente como ele funciona - deslizando por cima do arquivo com uma janela de duas linhas. Vou adicionar um comando \n ook pouco antes do l :
sed '$!N;/\nage.*: 10/P;l;D'
Name is : sara
Name is : sara\nage is : 10$
age is : 10\nName is : john$
Name is : john\nage is : 20$
age is : 20\nName is : Ron$
Name is : Ron
Name is : Ron\nage is : 10$
age is : 10\nName is : peggy$
Name is : peggy\nage is : 30$
age is : 30$
Essa é a saída. As linhas que terminam em D são o resultado do comando $ ook - que renderiza uma versão de escape do espaço padrão para stdout. As linhas que não terminam em l são aquelas que, de outra forma, seriam $ rinted. Como você pode ver, a linha anterior é apenas P rinted quando a segunda linha no espaço padrão - a linha P ext como apenas puxada e que segue a N ewline no espaço padrão - corresponde ao seu padrão. p>
Além das soluções já oferecidas, outra maneira de imprimir apenas as linhas Nome que precedem uma linha idade que não termina em 10:
sed -n '/^Name/N;/ 10$/!s/\nage.*//p'
... que acrescenta apenas um \n ewline seguido da linha de entrada \n ext se o espaço de padrão começar com a string Name , e somente N rints uma linha para saída se espaço padrão não termina com a string 10 e se p puder com êxito sed ubstitute a s/// ewline seguido da string age e tudo o que segue até a cauda do espaço padrão. Como não pode haver um \n ewline no espaço padrão, exceto como resultado de um comando de edição - como \n ext - o garante que as únicas linhas Nome impressas sejam aquelas imediatamente anteriores a idade linha que não termina na string 10 .
Toda a sintaxe usada na resposta acima é padrão POSIX - deve funcionar como escrito com qualquer N que suporte o padrão.