@Ed Morton: Eu discordo de você aqui. Achei sed
muito útil e simples (depois de entender o conceito do padrão e manter os buffers) criar uma maneira elegante de fazer o grep de várias linhas.
Por exemplo, vamos pegar um arquivo de texto que contém nomes de host e algumas informações sobre cada host, com muito lixo entre as quais eu não me importo.
Host: foo1
some junk, doesnt matter
some junk, doesnt matter
Info: about foo1 that I really care about!!
some junk, doesnt matter
some junk, doesnt matter
Info: a second line about foo1 that I really care about!!
some junk, doesnt matter
some junk, doesnt matter
Host: foo2
some junk, doesnt matter
Info: about foo2 that I really care about!!
some junk, doesnt matter
some junk, doesnt matter
Para mim, um script awk para obter apenas as linhas com o nome do host e a info
linha correspondente levaria um pouco mais do que sou capaz de fazer com o sed:
sed -n '/Host:/{h}; /Info/{x;p;x;p;}' myfile.txt
a saída se parece com:
Host: foo1
Info: about foo1 that I really care about!!
Host: foo1
Info: a second line about foo1 that I really care about!!
Host: foo2
Info: about foo2 that I really care about!!
(Observe que Host: foo1
aparece duas vezes na saída.)
Explicação:
-n
desativa a saída, a menos que seja explicitamente impresso
- primeira correspondência, encontra e coloca a
Host:
linha no buffer de retenção (h)
- segunda correspondência, encontra a próxima linha Info:, mas primeiro troca (x) a linha atual no buffer de padrão com o buffer de retenção e imprime (p) a
Host:
linha, depois troca novamente (x) e imprime (p) a linha Info :.
Sim, este é um exemplo simplista, mas eu suspeito que este seja um problema comum que foi rapidamente resolvido por uma linha simples do sed. Para tarefas muito mais complexas, como aquelas nas quais você não pode confiar em uma determinada sequência previsível, o awk pode ser mais adequado.
echo $'1\n2\n3\n4' | sed -n '1~2h;2~2{p;x;p}'