Editor de fluxo - Gerenciando padrões

Já discutimos o uso de pattern e hold buffer. Neste capítulo, vamos explorar mais sobre seu uso. Vamos discutir oncomando que imprime o espaço do padrão. Ele será usado em conjunto com outros comandos. A seguir está a sintaxe do comando then.

[address1[,address2]]n

Vamos dar um exemplo.

[jerry]$ sed 'n' books.txt

Quando o código acima for executado, ele produzirá o seguinte resultado:

1) A Storm of Swords, George R. R. Martin, 1216 
2) The Two Towers, J. R. R. Tolkien, 352 
3) The Alchemist, Paulo Coelho, 197 
4) The Fellowship of the Ring, J. R. R. Tolkien, 432 
5) The Pilgrimage, Paulo Coelho, 288 
6) A Game of Thrones, George R. R. Martin, 864

o n O comando imprime o conteúdo do buffer de padrão, limpa o buffer de padrão, busca a próxima linha no buffer de padrão e aplica comandos nele.

Vamos considerar que existem três comandos SED antes n e dois comandos SED após n do seguinte modo:

Sed command #1 
Sed command #2 
Sed command #3 
n command 
Sed command #4 
Sed command #5

Nesse caso, o SED aplica os três primeiros comandos no buffer de padrão, limpa o buffer de padrão, busca a próxima linha no buffer de padrão e, a partir daí, aplica o quarto e o quinto comandos nele. Este é um conceito muito importante. Não vá em frente sem ter uma compreensão clara disso.

O buffer de retenção contém dados, mas os comandos SED não podem ser aplicados diretamente no buffer de retenção. Portanto, precisamos trazer os dados do buffer de retenção para o buffer de padrão. SED fornece oxcomando para trocar o conteúdo do padrão e manter buffers. Os comandos a seguir ilustram ox comando.

Vamos modificar um pouco o arquivo books.txt. Digamos que o arquivo contém títulos de livros seguidos dos nomes dos autores. Após a modificação, o arquivo deve ficar assim:

[jerry]$ cat books.txt

Ao executar o código acima, você obtém o seguinte resultado:

A Storm of Swords 
George R. R. Martin 
The Two Towers 
J. R. R. Tolkien 
The Alchemist 
Paulo Coelho 
The Fellowship of the Ring 
J. R. R. Tolkien 
The Pilgrimage 
Paulo Coelho 
A Game of Thrones 
George R. R. Martin

Vamos trocar o conteúdo dos dois buffers. Por exemplo, o exemplo a seguir imprime apenas os nomes dos autores.

[jerry]$ sed -n 'x;n;p' books.txt

Ao executar o código acima, você obtém o seguinte resultado:

George R. R. Martin 
J. R. R. Tolkien 
Paulo Coelho 
J. R. R. Tolkien 
Paulo Coelho 
George R. R. Martin

Vamos entender como funciona esse comando.

  • Inicialmente, o SED lê a primeira linha, ou seja, A Storm of Swords no buffer de padrão.

  • x comando move esta linha para o buffer de espera.

  • n busca a próxima linha, ou seja, George RR Martin no buffer de padrão.

  • O controle passa para o comando seguido por n que imprime o conteúdo do buffer de padrão.

  • O processo se repete até que o arquivo se esgote.

Agora vamos trocar o conteúdo dos buffers antes de imprimir. Adivinhe, o que acontece? Sim, ele imprime os títulos dos livros.

[jerry]$ sed -n 'x;n;x;p' books.txt

Ao executar o código acima, você obtém o seguinte resultado:

A Storm of Swords 
The Two Towers 
The Alchemist 
The Fellowship of the Ring 
The Pilgrimage 
A Game of Thrones

o hcomando lida com o buffer de retenção. Ele copia dados do buffer de padrão para o buffer de retenção. Os dados existentes do buffer de retenção são sobrescritos. Observe que ohcomando não move dados, ele apenas copia dados. Conseqüentemente, os dados copiados permanecem como estão no buffer de padrão. Dada a seguir está a sintaxe doh comando.

[address1[,address2]]h

O comando a seguir imprime apenas os títulos do autor Paulo Coelho.

[jerry]$ sed -n '/Paulo/!h; /Paulo/{x;p}' books.txt

Ao executar o código acima, você obtém o seguinte resultado:

The Alchemist 
The Pilgrimage

Vamos entender como funciona o comando acima. O conteúdo de books.txt segue um formato específico. A primeira linha é o título do livro seguido pelo autor do livro. No comando acima, "!" é usado para reverter a condição, ou seja, a linha é copiada para o buffer de retenção apenas quando uma correspondência de padrão não é bem-sucedida. E as chaves {} são usadas para agrupar vários comandos SED

Na primeira passagem do comando, SED lê a primeira linha, ou seja, Uma Tempestade de Espadas no buffer de padrão e verifica se ele contém o padrão Paulo ou não. Como a correspondência de padrão não é bem-sucedida, ele copia essa linha para o buffer de retenção. Agora, tanto o buffer de padrão quanto o buffer de espera contêm a mesma linha, ou seja, A Storm of Swords. Na segunda etapa, ele verifica se a linha contém o padrão Paulo ou não. Como o padrão não corresponde, ele não faz nada.

Na segunda passagem, ele lê a próxima linha George RR Martin no buffer de padrão e aplica as mesmas etapas. Nas próximas três linhas, ele faz a mesma coisa. No final da quinta passagem, ambos os buffers contêm O Alquimista. No início da sexta passagem, ele lê a linha Paulo Coelho e como o padrão corresponde, ele não copia esta linha no buffer de espera. Portanto, o buffer de padrão contém Paulo Coelho, e o buffer de espera contém O Alquimista.

Depois disso, ele verifica se o buffer de padrão contém o padrão Paulo. Conforme a correspondência de padrão é bem-sucedida, ele troca o conteúdo do buffer de padrão pelo buffer de retenção. Agora, o buffer de padrão contém The Alchemist e o buffer de espera contém Paulo Coelho. Finalmente, ele imprime o conteúdo do buffer de padrão. As mesmas etapas são aplicadas ao padrão The Pilgrimage.

o hcomando destrói o conteúdo anterior do buffer de retenção. Isso nem sempre é aceitável, pois às vezes precisamos preservar o conteúdo. Para este efeito, o SED fornece oHcomando que anexa o conteúdo ao buffer de retenção adicionando uma nova linha no final. A única diferença entreh e Hé, o primeiro sobrescreve os dados do buffer de espera, enquanto o último acrescenta os dados ao buffer de espera. Sua sintaxe é semelhante àh comando.

[address1[,address2]]H

Vejamos outro exemplo. Desta vez, em vez de imprimir apenas títulos de livros, imprima também os nomes de seus autores. O exemplo a seguir imprime os títulos dos livros seguidos dos nomes dos autores.

[jerry]$ sed -n '/Paulo/!h; /Paulo/{H;x;p}' books.txt

Ao executar o código acima, você obtém o seguinte resultado:

The Alchemist 
Paulo Coelho 
The Pilgrimage
Paulo Coelho

Aprendemos como copiar / acrescentar o conteúdo do buffer de padrão para manter o buffer. Podemos executar a função reversa também? Sim certamente! Para este efeito, o SED fornece ogcomando que copia dados do buffer de retenção para o buffer de padrão. Durante a cópia, os dados existentes do espaço do padrão são sobrescritos. Dada a seguir está a sintaxe dog comando.

[address1[,address2]]g

Vamos considerar o mesmo exemplo - imprimir títulos de livros e seus autores. Desta vez, imprimiremos primeiro o nome do autor e, na próxima linha, o título do livro correspondente. O comando a seguir imprime o nome do autor Paulo Coelho, seguido do título do livro.

[jerry]$ sed -n '/Paulo/!h; /Paulo/{p;g;p}' books.txt

Ao executar o código acima, você obtém o seguinte resultado:

Paulo Coelho 
The Alchemist 
Paulo Coelho 
The Pilgrimage

O primeiro comando é mantido como está. No final da quinta passagem, ambos os buffers contêm O Alquimista. No início da sexta passagem, ele lê a linha Paulo Coelho e como o padrão corresponde, ele não copia esta linha no buffer de espera. Portanto, o espaço do padrão contém Paulo Coelho e o espaço de espera contém O Alquimista.

A partir daí, ele verifica se o espaço do padrão contém o padrão Paulo. Quando a correspondência de padrões é bem-sucedida, primeiro imprime o conteúdo do espaço de padrões, ou seja, Paulo Coelho, depois copia o buffer de retenção para o buffer de padrões. Conseqüentemente, os buffers de padrão e de espera contêm O Alquimista. Finalmente, ele imprime o conteúdo do buffer de padrão. As mesmas etapas são aplicadas ao padrão The Pilgrimage.

Da mesma forma, podemos anexar o conteúdo do buffer de retenção ao buffer de padrão. SED fornece oG comando que anexa o conteúdo ao buffer de padrão adicionando uma nova linha no final.

[address1[,address2]]G

Agora tomemos o exemplo anterior que imprime o nome do autor Paulo Coelhof seguido pelo título do livro. Para obter o mesmo resultado, execute o seguinte comando SED.

[jerry]$ sed -n '/Paulo/!h; /Paulo/{G;p}' books.txt

Ao executar o código acima, você obtém o seguinte resultado:

Paulo Coelho 
The Alchemist 
Paulo Coelho 
The Pilgrimage

Você pode modificar o exemplo acima para exibir os títulos dos livros seguidos por seus autores? Simples, basta trocar o conteúdo do buffer antes doG comando.

[jerry]$ sed -n '/Paulo/!h; /Paulo/{x;G;p}' books.txt

Ao executar o código acima, você obtém o seguinte resultado:

The Alchemist 
Paulo Coelho 
The Pilgrimage 
Paulo Coelho