6
Curso de Shell - Aula VI Por: Alex Borro ( 26/12/2000 ) Nesta aula continuaremos nosso tutorial, desta vez falando sobre o Sed. Vale lembrar que este tutorial dará uma breve introdução ao Sed, ajudando os iniciantes a entender como ele funciona. Portanto muitos comandos mais complexos serão omitidos, já que seria necessário um livro inteiro para ensinar tudo sobre o Sed. Mas não se preocupem, ensinaremos o suficiente sobre ele para utilização em shell script. Resumo de RegExp Vamos a um resumo sobre as expressões regulares, explicadas na aula anterior e agora aplicadas ao Sed: ^ casa com o começo de linha $ casa com o fim de linha . casa com qualquer caracter simples (apenas um) (caracter)* casa com qualquer ocorrência, em qualquer quantidade, de (caracter) (caracter)? casa com zero ou uma ocorrência de (caracter) [abcdef] Casa com qualquer caracter dentro dos [ ] (neste caso, a b c d e ou f), faixas de caracteres como [a-z] são permitidas. [^abcdef] Casa com qualquer caracter NÃO incluído em [] (neste caso, qualquer caracter que não seja a b c d e ou f) (caracter)\{m,n\} casa com m-n repetições de (caracter) (caracter)\{m,\} casa com m ou mais repetições de (caracter) (caracter)\{,n\} casa com n ou menos (também zero) repetições de (caracter) (caracter)\{n\} casa com exatamente n repetições de (caracter) \(expressão\) operador de grupo. \n Backreference - casa com o n-ésimo grupo expressão1\|expressão2 Casa com expressão1 ou expressão2. Funciona com o GNU sed, mas essa característica pode não funcionar com outros Seds. Caracteres Especiais Os caracteres especiais no Sed são os mesmo do Grep, com uma diferença: a barra normal / é um caracter especial no sed. A razão disso ficará clara mais para frente quando estudarmos os comandos do sed. Como funciona: Uma breve introdução O Sed funciona assim: ele lê da entrada padrão, uma linha de cada vez. Para cada linha, ele executa uma série de comandos de edição e então a linha é escrita na saída padrão. Um exemplo que mostra como ele funciona: Nós usamos o comando "s", que significa "substitute" (substituir) ou "search and replace" (procurar e trocar). O formato é: s/expressão-regular/texto-substituto/{flags} Nós não vamos discutir todas as flags ainda. A única que usamos abaixo é a "g", que significa "substitua todas as ocorrências": >cat file Eu tenho três cachorros e dois gatos >sed -e 's/cachorros/gatos/g' -e 's/gatos/elefantes/g' file http://olinux.uol.com.br/artigos/314/print_preview.html

Curso De Shell Aula 6

Embed Size (px)

Citation preview

Page 1: Curso De Shell   Aula 6

Curso de Shell - Aula VI Por: Alex Borro ( 26/12/2000 )

Nesta aula continuaremos nosso tutorial, desta vez falando sobre o Sed. Vale lembrar que este tutorial dará uma breve introdução ao Sed, ajudando os iniciantes a entender como ele funciona. Portanto muitos comandos mais complexos serão omitidos, já que seria necessário um livro inteiro para ensinar tudo sobre o Sed. Mas não se preocupem, ensinaremos o suficiente sobre ele para utilização em shell script.

Resumo de RegExp

Vamos a um resumo sobre as expressões regulares, explicadas na aula anterior e agora aplicadas ao Sed:

^ casa com o começo de linha$ casa com o fim de linha. casa com qualquer caracter simples(apenas um)(caracter)* casa com qualquer ocorrência, em qualquerquantidade, de (caracter)(caracter)? casa com zero ou uma ocorrência de(caracter)[abcdef] Casa com qualquer caracter dentro dos [ ](neste caso, a b c d e ou f), faixas de caracteres como [a-z] sãopermitidas. [^abcdef] Casa com qualquer caracter NÃOincluído em [] (neste caso, qualquer caracter que não seja a b c d e ou f)(caracter)\{m,n\} casa com m-n repetições de (caracter)(caracter)\{m,\} casa com m ou mais repetições de(caracter)(caracter)\{,n\} casa com n ou menos (também zero)repetições de (caracter)(caracter)\{n\} casa com exatamente n repetiçõesde (caracter)\(expressão\) operador de grupo.\n Backreference - casa com o n-ésimo grupo expressão1\|expressão2 Casa com expressão1 ouexpressão2. Funciona com o GNU sed, mas essa característica pode não funcionar com outros Seds.

Caracteres Especiais

Os caracteres especiais no Sed são os mesmo do Grep, com uma diferença: a barra normal / é um caracter especial no sed. A razão disso ficará clara mais para frente quando estudarmos os comandos do sed.

Como funciona: Uma breve introdução

O Sed funciona assim: ele lê da entrada padrão, uma linha de cada vez. Para cada linha, ele executa uma série de comandos de edição e então a linha é escrita na saída padrão. Um exemplo que mostra como ele funciona: Nós usamos o comando "s", que significa "substitute" (substituir) ou "search and replace" (procurar e trocar). O formato é:

s/expressão-regular/texto-substituto/{flags}

Nós não vamos discutir todas as flags ainda. A única que usamos abaixo é a "g", que significa "substitua todas as ocorrências":

>cat file Eu tenho três cachorros e dois gatos >sed -e 's/cachorros/gatos/g' -e 's/gatos/elefantes/g' file

http://olinux.uol.com.br/artigos/314/print_preview.html

Page 2: Curso De Shell   Aula 6

Eu tenho três elefantes e dois elefantes

OK, então o que aconteceu? Primeiro o sed leu a linha do arquivo "file" e executou:

s/cachorros/gatos/g

que produziu o seguinte texto:

Eu tenho três gatos e dois gatos

e então o segundo comando foi executado na linha jáeditada e resultou:

Eu tenho três elefantes e dois elefantes

Nós atualmente damos um nome para o texto (geralmente uma linha) que o sed leu e está processando (editando): ele chama-se "pattern space" (uma boa tradução seria "área de edição").

O sed lê da entrada padrão e joga na sua área de edição, executando nela uma seqüência de comandos de edição e então ele escreve o resultado na saída padrão.

Comandos de Substituição e Deleção

Primeiro, as maneiras mais usuais do sed é a seguinte:

>sed -e 'comando1' -e 'comando2' -e 'comando3' arquivo >{comando shell} | sed -e 'comando1' -e 'comando2' >sed -f sedscript.sed arquivo >{comando shell} | sed -f sedscript.sed

Então, o sed pode ler do arquivo ou da entrada padrão, e os comandos podem ser especificados em um arquivo de script ou na linha de comando. Esse arquivo, chamado sedscript.sed é um arquivo que contém todos os comandos do sed, ao invés de serem especificados na linha de comando. Esses sed's scripts são úteis quando precisamos de um processamento de texto mais complexo e refinado.

Note o seguinte: se os comandos são lidos de um arquivo (sed script), espaços em branco podem ser fatais. Eles podem fazer o script falhar sem explicação aparente. Eu recomendo editar os arquivos de comandos do sed com um editor como o VIM que pode mostrar o final da linha e você pode ver se existem espaços em branco entre os comandos e o fim da linha.

Comando de Substituição

O formato para o comando de substituição é o seguinte:

[endereço1[,endereço2]]s/procura/substituto/[flags]

As flags podem ser as seguinte:

n troca a n-ésima ocorrência (na linha) do texto "procura" por "substituto"g troca todas as ocorrências (na linha) dotexto "procura" por "substituto"p imprime a "área de edição" para asaída padrão se ocorrer uma substituição comsucessow arquivo imprime a "área de edição" para arquivose ocorrer uma substituição com sucesso

Se nenhuma flag for especificada, somente a primeira ocorrências na linha é substituída. Note que nós quase sempre usamos o comando "s" ou com a flag "g" ou sem nenhuma flag.

Se um endereço é dado, então a substituição é aplicada a linhas que contenham aquele endereço. Um endereço pode ser ou uma expressão regular dentro de barras normais /regexp/ , ou um número de linha. O símbolo $ pode ser usado no lugar do número da linha para denotar a última linha.

Page 3: Curso De Shell   Aula 6

Se dois endereços são fornecidos, separados por uma vírgula, então a substituição é aplicada a todas as linhas entre duas linhas que casam com os endereços fornecidos.

Isto requer algum esclarecimento. Mais precisamente, a substituição ocorre em todas as linhas desde a primeira ocorrência de "endereço1" até a primeira ocorrência de "endereço2".

Não se preocupe se isso tudo parece meio confuso. Os exemplos vão esclarecer melhor.

O comando de Deleção

A sintaxe desse comando é muito simples. Ai vai:

[endereço1[,endereço2]]d

Isto deleta o conteúdo da "área de edição" (se esta casar com os endereços fornecidos). Todos os comandos seguintes serão pulados (já que não a nada a fazer com uma área de edição em branco) e uma nova linha será lida e jogada na área de edição e todo o processo se repete.

Exemplos:

Exemplo 1:

>cat file O gato preto foi caçado por um cachorro marrom. >sed -e 's/preto/branco/g' file O gato branco foi caçado por um cachorro marrom.

Exemplo 2:

>cat file O gato preto foi caçado por um cachorro marrom. O gato preto não foi caçado por um cachorro marrom. >sed -e '/não/s/preto/branco/g' file O gato preto foi caçado por um cachorro marrom. O gato branco não caçado por um cachorro marrom.

Neste caso, a substituição é aplicada somente a linhas que casam com a expressão regular "/não/". Portanto, ela não é aplicada a primeira linha, pois esta não contem a palavra "não".

Exemplo 3:

>cat file linha 1 (um) linha 2 (dois) linha 3 (três)

Exemplo 3a:

>sed -e '1,2d' file linha 3 (três)

Exemplo 3b:

>sed -e '3d' file linha 1 (um) linha 2 (dois)

Exemplo 3c:

>sed -e '1,2s/linha/LINHA/' file LINHA 1 (um) LINHA 2 (dois) linha 3 (três)

Exemplo 3d:

>sed -e '/^linha.*um/s/linha/LINHA/' -e '/linha/d' file

Page 4: Curso De Shell   Aula 6

LINHA 1 (um)

3a : Este foi bem simples: Nós apenas deletamos as linhas de 1até 23b : Isto também foi simples: Nós deletamos a linha 3.3c : Neste exemplo, nós fizemos uma substituição naslinhas 1 até 2.3d : Agora este é mais interessante e merece algumasexplicações.

O primeiro comando vai procurar "^linha.*um" e substituir "linha" por "LINHA", ou seja, somente a primeira linha casa com essa expressão regular. O segundo comando diz para o sed deletar linhas que contenham a palavra "linha". Assim, somente as duas últimas linhas serão deletadas, já que a primeira teve palavra "linha" substituída por "LINHA".

Exemplo 4:

>cat file olá Este texto será cortado olá (também será retirado) ReTiRaDo Também!!! tchau (1) Este texto não foi apagado (2) nem este ... ( tchau ) (3) nem este olá mas este será e este também e a menos que nós encontremos outro tch*u cada linha até o final do texto será apagada

>sed -e '/olá/,/tchau/d' file

(1) Este texto não foi apagado (2) nem este ... ( tchau ) (3) nem este

Isto mostra como o endereçamento funciona quando dois endereços são especificados. O sed encontra o primeiro casamento da expressão "olá" e deleta todas as linhas lidas na área de edição até ele encontrar a primeira linha que contém a expressão "tchau" (está também será apagada). Ele não aplica mais o comando de deleção para nenhuma linha até encontrar novamente a expressão "olá". Desde que a expressão "tchau" não ocorre mais em nenhuma linha subseqüente, o comando de deleção é aplicado até o final do texto.

Resumindo, é simples: Quando ele encontra o primeiro endereço ("olá") ele passa a executar os comandos até encontrar o segundo endereço ("tchau") ou o fim do texto. E isso se repete até acabar o texto.

Exemplo 5:

>cat file http://www.kernel.org/ >sed -e 's@http://www.kernel.org@http://www.metalab.unc.edu@' file http://www.metalab.unc.edu/

Note que nós usamos um delimitador diferente, @ para o comando de substituição. O Sed permite diversos delimitadores para o comando de substituição, incluindo @ % , ; : Esses delimitadores alternativos são bons para substituições que incluem string como nome de arquivos e outras que contém barra normal /, o que torna o código do sed muito mais legível.

Mais alguns comandos

Aqui veremos mais alguns comandos sobre o sed, a maioria deles mais complexos. Dependendo da aplicação em que vocês forem usar o sed, dificilmente usarão esses recursos, a menos que precisem de um processamento de texto mais refinado e complexo. Veja que eles são muito usado nos scripts do

Page 5: Curso De Shell   Aula 6

sed (não confunda com shell-script).

Backreference no Sed

Uma das coisas legais sobre backreference no sed é que você pode usar não apenas em procura de textos mas também na substituição de textos.

O comando Quit

O comando quit ou "q" é muito simples. Ele simplesmente termina o processamento. Nenhuma outra linha é lida para a área de edição ou impressa na saída padrão.

Sub-rotinas

Nós agora introduzimos o conceito de sub-rotinas no sed:

No sed, as chaves { } são usadas para agrupar comandos. Elas são usadas dessa maneira:

endereço1[,endereço2]{comandos}

Exemplo: Encontrar uma palavra de uma lista num arquivo

Este exemplo faz um bom uso dos conceitos descritos acima.

Para isto, nos usamos um shell-script, desde que os comandos são muito longos e precisaríamos escrever a longa string X várias vezes. Note que usamos aspas duplas, já que a variável $X precisa ser expandida pelo shell. A sintaxe para rodar esse script é: "script arquivo", onde "script" é o nome dado ao script e "arquivo" é o nome do arquivo a procurar uma palavra da lista.

#!/bin/shX='word1\|word2\|word3|\word4|\word5'sed -e " /$X/!d/$X/{ s/\($X\).*/\1/ s/.*\($X\)/\1/ q }" $1

Uma nota importante: é tentador pensar que:

s/\($X\).*/\1/ s/.*\($X\)/\1/

é redundante e tentar encurta-la para:

s/.*\($X\).*/\1/

Mas isto não funciona. Por que? Suponha que temos a linha:

word1 word2 word3

Nós não temos como saber se $X vai casar com word1, word2 ou word3, então quando nós citamos ele (\1), nós não sabemos quais dos termos está sendo citado. O que está sendo usado para certificar-se que não há problemas na correta implementação, é isto:

"O operador * é guloso. Ou seja, quando há ambigüidade sobre qual (expressão)* pode casar, ele tentar casar o máximo possível."

Então neste exemplo, s/\($X\).*/\1/ , .* tenta engolir o máximo da linha possível, em particular, se a linha contém isso:

"word1 word2 word3"

Então nós podemos ter certeza que .* casa com " word2 word3" e portanto $X seria word1. Não se preocupem se não entenderam muito bem este tópico. Ele é complicado mesmo e pouco usado. O importante é entender como ele funciona, o uso de regexp e do comando de substituição e deleção. Para maiores informações sobre o sed, dê uma olhada na sua man page: "man sed"

Page 6: Curso De Shell   Aula 6

Espero que vocês tenham gostado desse pequeno tutorial sobre sed. Como disse na aula anterior sobre o Grip, é praticando que se aprende a usar ele.

O fim...

Bom pessoal, acho que nosso curso termina por aqui. Claro que não deu pra cobrir tudo sobre shell script, se não nosso curso não teria fim. Tentei abordar os topicos mais importantes, de modo que vcs tenham uma boa noção de como funciona as coisas no shell e possam dar os proprios passos. Desculpem se esqueci de falar sobre alguma coisa que vocês estavam esperando. Como disse, estou a disposição para resolver qualquer dúvidas.

Abraços, Alex Borro

Copyright (C) 1999-2000 Linux Solutions