CI066 - Oficina de Programação
Notas de Aula # 11

Prof. Armando Luiz N. Delgado

1 Filtros avançados: sed(1) (Stream Editor)

OBS.: Para outras referências, veja os links http://sed.sourceforge.net e http://www.inf.ufpr.br/nicolui/grad/ci066/sed/


sed(1) é um dos comandos mais usados no processamento de textos em UNIX. Este comando permite a aplicação de transformações sobre uma entrada vinda de um arquivo, de um pipeline ou de STDIN. sed(1) não é um editor interativo como vi(1) ou gedit(1).

A sintaxe geral de sed(1) é: sed -e comando_edição [arquivo] onde comando_edição é aplicado em cada linha do arquivo especificado. Se nenhum arquivo é indicado, sed(1) lê os dados de STDIN. O argumento comando_edição apresenta o seguinte formato:

         [endereço-1[,endereço-2]] função [argumento]

A porção endereço-1[,endereço-2] pode tanto indicar a linha onde função será aplicada, quanto uma expressão regular. endereço-1 indica a linha inicial e endereço-2 a linha final. Por exemplo, o endereço 1,5 indica que a função será aplicada da 1ª linha até a 5ª .

função [argumento] representa a ação que será aplicada em cada linha que corresponda ao endereço especificado. Se o endereço é omitido, função é aplicada em todas as linhas.

As principais funções de sed(1) são mostradas na Tabela 1:


Tabela 1: Comandos de sed(1)
Função Descrição Formato Exemplo
s Substituição s/antigo/novo[/flags] o caracter / pode ser substituído por qualquer outro caracter. sed -e 's/unix/Unix/g' teoria.txt sed -e 's#/usr/local#/usr/share/bin#g' web.sh
       
d Remoção d sed -e '1,5d' teoria.txt
       
q Termina execução q sed -e '/Windows/q' teoria.txt
       
p Imprime a linha p sed -e '/Windows/p' teoria.txt
       
a Insere texto após linha atual a$\backslash$ texto sed -e '/Windows/a$\backslash$ MS-Windows' teoria.txt
       
i Insere texto antes de linha atual i$\backslash$ texto sed -e '/Windows/i$\backslash$ MS-Windows' teoria.txt
       
c Troca linha atual pelo texto especificado c$\backslash$ texto sed -e '/Windows/c$\backslash$ MS-Windows' teoria.txt
       
r Insere conteúdo de arquivo após linha atual r arquivo sed -e '/Unix/r novotexto.txt' teoria.txt


2 Filtros avançados: awk(1)

OBS.: Esta seção é uma reprodução do material de CI066 do Prof. Luciano Silva. Para outras referências, veja os links http://www.gnu.org/manual/gawk/ e http://www.inf.pucrs.br/~manssour/AWK/index.html


awk(1) é um comando usado para processamento de texto, principalmente em arquivos com colunas. Possui uma linguagem própria para a definição do processamento e funções pré-definidas para operações matemáticas e manipulação de strings.

Opções:

-F":-> define dois-pontos como separador de campos. O padrão é qualquer combinação de espaços e tabs.

/er/ -> para busca de expressão regular

'print' -> imprime resultado da busca, ou campos específicos

FS -> variável separador de campos NR -> variável para numerar linhas NF -> variável para número de campos na linha

Funções:

length(variavel) -> retorno o tamanho da string. length($2)

sub(/er/,"string",variavel -> substitui a expressão regular pela string na variável. $0 é a variável default

Exemplos:

Filtra as linhas com o padrão especificado. Abaixo, filtra linhas que terminam com conf:

        ls -l /etc | awk /conf\$/

Usando outro separador de campos e imprimindo coluna 1:

        cat /etc/passwd | awk -F: '{print \$1}'

Usando separador de campos:

        ls -l /etc |awk '{print \$1 FS \$8}'

Numerando linhas:

        ls -l /etc |awk '{print NR FS\$1 FS \$8}'

Filtra linhas com padrão especificado e mostra apenas as colunas 1 e 8:

        ls -l /etc |awk '/conf\$/{print \$1" "\$8}'

Imprime as linhas com mais de 3 campos. Elimina a primeira linha do ls  -l (Total):

        ls -l /etc | awk 'NF > 3'

Filtra linhas com arquivos cujos nomes possuem menos de 5 caracteres:

        ls -l /etc | awk 'length(\$8) < 5'

Imprime linhas pares:

        ls -l /etc | awk 'NR \% 2 == 0 {print NR" "\$0}'

Substitui strings:

        ls -l /etc | awk '{sub(/conf\$/,"test"); print \$0}'

Procura expressão em determinado campo:

        ls -l /etc | awk '\$8 ~ /^[ae]/'

Inserindo strings entre campos:

        cat /etc/passwd | awk -F: '{print "Login: " \$1}'

3 Manipulação de strings: expr(1)

expr(1) é um programa usado em programação shell para manipulação de strings. As principais formas de manipulação de strings com expr(1) são mostradas na tabela 2.


Tabela 2: Manipulação de strings com expr(1)
Função Descrição Exemplo
     
match STRING REGEXP Procura em STRING pela expressão regular REGEXP. Retorna o número de caracteres em STRING que coincidem com REGEXP. Se REGEXP usa uma sub-expressão limitada por $\backslash$(   $\backslash$), retorna a parte de STRING que coincide com o padrão dentro da sub-expressão. expr  match  $NOME"  '[a-z].*'
     
substr STRING POS LENGTH Extrai LENGTH caracteres de STRING, começando da posição POS (para primeiro caracter, POS=1) expr  substr  $NOME"  3  4
     
index STRING CHARS índice em STRING onde qualquer um dos caracteres em CHARS ocorre primeiro. Retorna 0 (zero) se não acha caracteres. expr  index  Cardoso  cdCD
     
length STRING comprimento do string. expr  length  $NOME


4 Cálculos com números em ponto flutuante: bc(1)

OBS.: Esta seção é uma reprodução do material de CI066 do Prof. Luciano Silva.


Usa-se bc(1) para fazer o cálculo usando ponto flutuante e o retorno do comando é geralmente atribuido a uma variável do programa.

Com bc(1) você pode alterar o número de dígitos após o ponto. Para isso usa-se a função scale. Se você não usar scale e colocar a opçao -l ao executar bc(1) o número de dígitos após o ponto passa a ser 20.

Você pode fazer uso também de variáveis em bc(1):

            a=5
            b=3.2
            echo "$a + $b" | bc -l
            8.2

Pode-se atribuir o resultado a uma variável:

            soma=20 
            media=$(echo "$soma/7" | bc -l)
            echo $media

Para alterar as casas decimais, usa-se scale:

            echo "0.5/11 + 1.0" | bc -l
            1.04545454545454545454

            echo "scale=3; 0.5/11 + 1.0" | bc
            1.045

Internamente em bc(1) você pode declarar variáveis:

            bc -l
            a=5
            b=4.2
            a*b
            21.0

Eexemplo interessante de uso para expressões grandes:

           n1=5.5
           n2=4.2
           n3=6.1
           media=$( bc << FIM
             scale=3
             soma=($n1+$n2+$n3)
             soma/3
           FIM
           )
           echo $media

bc(1) possui diversas funções matemáticas pré-definidas como seno, coseno, raiz quadrada, etc.:

           bc -l
           sqrt (20)
           4.47213595499957939281

É possível ainda usar bc(1) para teste de expressão, por exemplo se $var1 > 4.34$. O resultado é $1$ para verdadeiro e $0$ (zero) para falso:

            bc
            3.4 > 2
            1

Isto em um programa shell fica

            a=7.1 
            res=$(echo "$a > 5"| bc -l)
            if (( $res == 1 ))
            then
               echo verdadeiro
            fi

Uma operação interessante com inteiros é fazer a decomposição em fatores primos, usando o comando factor. Com este comando é possível saber se um número é primo. Por exemplo, 1777 é primo?:

           factor 52
           52: 2 2 13

5 Exemplos

Exemplos podem ser encontrados no link de Exemplos na página HTML da disciplina.



Armando Luiz Nicolini Delgado
2008-10-06