• Revista PROGRAMAR: Já está disponível a edição #53 da revista programar. Faz já o download aqui!

Njay

[TCL] Processar ficheiros de texto

1 mensagem neste tópico

Bom, como TCL é a minha linguagem de scripting favorita e já vi que não há por aqui nada sobre ela, resolvi começar com simples processamento de texto.

Carregar o conteúdo de um ficheiro para uma variável?

proc load {filename}  {
    set fd  [open $filename r]
    set data  [read $fd]
    close $fd
    return $data
}

Em TCL o open abre ficheiros, e os argumentos são simples, semelhantes a tantas outras linguagens de programação.

O comando (em TCL as "funções" chamam-se "comandos") read lê um ficheiro até ao fim, e o close naturalmente fecha-o.

Gravar o conteúdo de uma variável para ficheiro?

proc save {filename data}  {
    set fd  [open $filename w]
    puts -nonewline $fd $data
    close $fd
}

O puts é usado para escrever em ficheiros (na verdade em "canais", que é um conceito mais abrangente do que um ficheiro, mas vamos simplificar), e por omissão adiciona um fim de linha áquilo que escreve, daí a utilização do parâmetro -nonewline.

E agora, fazer um "grep" a um ficheiro?

proc grep {text filename}  {
    set data  [load $filename]
    set res  ""
    foreach line [split $data \n]  {
        if [string match "*$text*" $line]  {
            append res "$line\n"
        }
    }
    return $res
}

O comando split cria uma lista a partir de uma string, dividindo a string onde ocorrerem certos caracteres, eliminando-os; neste caso a divisão da string dá-se nos caracteres de fim de linha, e assim ficamos com uma lista em que cada elemento é uma linha do ficheiro.

De seguida usamos o comando foreach, que é usado para processar listas. À variável line vai sendo atribuído sequencialmente o valor de cada elemento da lista, e o corpo do comando é executado. Trata-se simplesmente de um ciclo em que a variável line percorre todos os elementos da lista dada, neste caso, a lista retornada pelo split.

O sub-comando match do comando string diz-nos se uma string faz match (condiz) com uma expressão glob (expressões com * e ? tal como usamos normalmente na linha de comando para ficheiros), retornando um valor boleano. Daí que, se a linha faz match com o texto que procuramos, essa linha é adicionada à string resultante (res), adicionando um fim de linha uma vez que este foi removido no split.

Claro que o grep poderia ter sido feito de uma forma muito mais simples invocandoo comando "grep" mas isso era batota :confused:, e assim ficam com um ciclo de processamento de ficheiros de texto linha a linha.

Já agora, podem facilmente guardar o resultado do grep num ficheiro, fazendo: save "results.txt" [grep ...].

E fazer um grep em vários ficheiros? Com uma expressão glob?

proc mgrep {text filemask}  {
    foreach filename [glob $filemask]  {
        if [file isfile $filename]  {
            puts "$filename:"
            puts [grep $text $filename]    ;# print the results for the current file
        }
    }
}

Aqui temos 2 comandos novos, o file e o glob.

O file serve essencialmente para processar e obter a meta-informação de ficheiros. Neste caso, o seu sub-comando isfile serve para destinguirmos os ficheiros das directorias e outros objectos do sistema de ficheiros.

O glob é uma espécie de "dir" (ou "ls" para quem gosta mais de unix), e retorna uma lista com os nomes dos ficheiros. Podemos passar expressões glob como argumento a este comando mgrep definido acima, pois o glob suporta-o, como por exemplo: mgrep casa *.txt.

E por agora é tudo...

Em TCL só existem 3 tipos de dados: strings, arrays que guardam strings, e listas que guardam strings ou outras listas. É bastante bom a processar texto linha a linha. E podemos fazer um pequeno pacote apenas com 2 ou 3 MB já contendo não só o interpretador de TCL mas também a biblioteca gráfica (Tk) e o ficheiro de ajuda. Esta "pequenez" tem feito com que o leve para todo lado e o use em N tipo de tarefas diárias em casa e no trabalho. E a biblioteca gráfica é espantosamente poderosa, especialmente tendo em conta o seu diminuto tamanho; há até quem diga que o melhor do TCL é o Tk :).

Fiquem bem!

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Crie uma conta ou ligue-se para comentar

Só membros podem comentar

Criar nova conta

Registe para ter uma conta na nossa comunidade. É fácil!


Registar nova conta

Entra

Já tem conta? Inicie sessão aqui.


Entrar Agora