Jedi Tux

Expressões regulares no Vim – Update 1

Posted in Vim by Fernando Basso on 31 de dezembro de 2011

Expressões Regulares no Vim

Boa parte do que está aqui é uma adapatação do :help usr_27.txt (arquivo de ajuda integrada do Vim).

Básico

Início e fim de linha

 :help 03.9 (Simple search patterns)

Use as opções :set incsearch e :set hlsearch para praticar. Para “resetar as cores”, :nohlsearch. Crie um arquivo com pedaços de texto que torne possível praticar as dicas aqui apresentadas.

O caractere ^ faz correspondência ao início da linha. O caractere $ corresponde ao fim da linha.

Econtra “teste” somente se estiver no final da linha:

 /teste$

Encontra teste somente se estiver no início da linha;

 /^teste

Encontra “teste” somente se ele for a única coisa da linha. Não pode haver espaços nem antes e nem depois de “teste”:

 /^teste$

Qualquer caractere uma vez

O . (ponto) corresponde a qualquer caractere – uma vez.

Corresponde a “abc”, “azc”, “aYz”, “a b”, “a-b”, etc:

 /a.b

Escapar caracteres especiais

Se queremos encontrar literalmente um ponto, devemos escapar o ponto, pois no vim ele é um caractere especial.

Se fizer somente

 /.

vai corresponder a todos os caracteres, até mesmo espaços em branco. Para encontrar somente o ponto literalmente:

    /\.

Escapando o . ele se torna um reles mortal e perde todos os seus superpoderes de caractere especial.

RegExp nível intermediário

:help usr_27.txt

Ignorando maiúsculas e minúsculas

Por padrão, o vim é sensível à caixa da letra. Portanto, “else”, “ELSE”, Else” são palavras diferentes. Para que o vim ignore a caixa da letra (case):

 :set ignorecase

Agora, tanto faz procurar por “else”, “ELSE”, ou “Else”, pois o vim vai tentar encontrar a palavra não importa quais letras nes estejam maiúsculas ou minúsculas.

Para voltar a se importar com o case da letra:

 :set noignorecase

Há também a opção smartcase, que é “ignorecase” por padrão, mas se você realizar a procura com pelo menos uma letra maiúscula o vim detecta e passa a ser sensível ao case automaticamente.

 :set ignorecase smartcase

Para fazer procura sensível à caixa em uma pesquisa apenas, usamos \C (maiúsculo):

 /\Cteste
 /\CTeste

O primeiro só combina com “teste”, todas minúsculas. O segundo só combina com “Teste” com o primeiro “T” maiúsculo.

Para tornar a pesquisa insensível ao case use \c (minúsculo):

 /\cteste

Encontra “teste”, “TESTE”, “teSTE”, etc.

A vantagem de usar \c e \C é que eles ficam no histórico junto com o ‘pattern’ da pesquisa.

NOTA: O uso de \ depende da opção magic. :help ‘magic’.

Offsets de linhas

Quando fazemos uma busca, o cursor para na linha da busca. Se queremos parar duas linhas após o elemento procurado:

 /teste/2

Offset de caracteres

Parar o cursor no último caractere do elemento procurado (e = end):

 /teste/e 

Coloca o cursor 3 caracteres após o último caractere do elemento procurado:

    /teste/e+3

Coloca o cursor no penúltimo caractere do elemento procurado:

 /teste/e-1

Coloca o cursor na segunda no terceiro caractere do elemento buscado (b = beggin):

 /teste/b+2

É b+2 por que b já é o primeiro caractere, então + 2 dá 3.

Estes offsets serão mais úteis quando estudarmos o conteúdo do :help pattern.txt.

Xdefaults VS Escape Sequences, Bash – Cores do Prompt

Posted in Bash, Dicas, Linux by Fernando Basso on 27 de dezembro de 2011

Leia todo o texto antes de tentar configurar algo. Algumas coisas que você ler mais no início do texto fará sentido quando se juntar com conceitos explicados mais adiante.

A intenção deste post não é mostrar TUDO sobre configuração do prompt do bash propriamente dito, mas sim mostrar a relação que tem as cores do terminal/prompt com as sequências de escape que usamos para configurar o prompt, pois sem essa noção, ficamos tentando configurar as cores “às cegas”. Esse tutorial funciona para o xterm, mas os conceitos são os mesmos para configurar outros emuladores de terminal.

Quando queremos configurar o prompt do Bash, usamos sequências de escape como:

    '\033[31m'
    

Faça um teste:

    echo -e "\033[31m Hello, World."

\033[ significa que estamos iniciando uma sequência de caracteres que não serão imprimidos, ou seja, inicia a sequência de escape. O próximo número (31, no exemplo) indica a cor que queremos imprimir, seguido de “m“, que termina a sequência de escape. O que vem em seguida é o texto que queremos realmente mostrar.

A parte numérica que determina a cor do texto pode indicar que queremos o texto em negrito, para isso, a sintaxe fica assim:

    echo -e '\033[31;1m Hello, World." # Note o ";1".

Ou seja, aquele 31;1, onde 31 é a cor, e 1 habilita o negrito. O número que especifica a cor e o número que habilita o negrito devem estar separados por ponto e vírgula (;). Mas agora vem a questão: 31 é qual cor? Aí é que entra o arquivo ~/.Xdefaults ou ~/.Xresourses.

No ~/.Xdefaults temos entradas como as do exemplo abaixo:


    ! Black, \033[30m
    XTerm*color0: #000000
    ! DarkGrey, \033[30;1m
    XTerm*color8: #BABDB6

    ! DarkRed, \033[31m
    XTerm*color1: #FF6565
    ! Red, \033[31;1m
    XTerm*color9: #FF8D8D

No ~/.Xdefaults usamos cores que vão de color0 até color15. As cores do color0 a color7 são cores normais, e de color8 até color15 são as cores em negrito, ou brilhosas.

Aqui temos um conceito importante. Note nos comentários (linhas iniciadas com !). Por exemplo, *color0 é a cor que será usada na sequência de escape \33[30m (cor normal), e a color8 será usada com a sequência \33[30;1m, ou seja, a cor em negrito. Continuando, color1 é usada pela sequência \33[31m (cor normal) e color9 é usada pela sequência \33[31;1m, a cor em negrito, e assim sucessivamente, até a color7 para cores normais, e color15 para os negritos.

Agora, configure as cores do xterm no ~/.Xdefaults da maneira que quiser, ou simplesmente copie as minhas (que pode modificar depois):

! ***** My Xterm Colors ***** ! {{{
! 1 to 7 are normal colors. 8 to 15 are the bright/bold ones.
XTerm*foreground: yellow
XTerm*background: #242424

! Black, \033[30m
XTerm*color0: #000000
! DarkGrey, \033[30;1m
XTerm*color8: #BABDB6

! DarkRed, \033[31m
XTerm*color1: #FF6565
! Red, \033[31;1m
XTerm*color9: #FF8D8D

! DarkGreen, \033[32m
XTerm*color2: green3
! Green, \033[32;1m
XTerm*color10: #C8E7A8

! DarkYellow, \033[33m
XTerm*color3: #EAB93D
! Yellow, \033[33;1m
XTerm*color11: #FFC123

! DarkBlue, \033[34m
XTerm*color4: #204A87
! Blue, \033[34;1m
XTerm*color12: #3465A4

! DarkMagenta, \033[35m
XTerm*color5: #CE5C00
! Magenta, \033[35;1m
XTerm*color13: #F57900

! DarkCyan, \033[36m
XTerm*color6: #89B6E2
! Cyan, \033[36;1m
XTerm*color14: #46A4FF

! LightGrey, \033[37m
XTerm*color7: #CCCCCC
! White, 0\33[37;1m
XTerm*color: #FFFFFF

! }}} Xterm ends here.

Para que as configurações entrem em vigor, execute o comando:

    xrdb ~/.Xdefaults

Feche e abra o terminal novamente. Lembre-se que isso funciona para o xterm. Não adianta usar o gnome-terminal (do gnome) ou o konsole (do kde). Agora sim estamos preparados para brincar com o prompt.

O prompt do bash é definido pela variável PS1 (tem a PS2 também, entre outras, que é usada quando continuamos um comando na próxima linha).

Vamos fazer uma configuração básica do prompt. Não precisa editar arquivo nenhum por enquanto, pois vamos fazer direto pelos comandos. Antes, porém, dê uma olhada nesta lista:

    \$ # Mostra o prompt de usuário '$', ou root '#'.
    \u # Mostra o username.
    \h # Mostra o hostname.
    \t # Mostra a hora (time).
    \d # Mostra a data (date).

Tem outros. man bash, na seção PROMPTING tem mais informações.

Digite o próximo comando, e veja como fica o prompt (não se preocupe, poi s essas alterações não são definitivas).

    PS1='\$ '

Agora tente este:

     PS1='\033[31m \$ '

Mais um:

    PS1='\033[31m\h@\u, \033[33m \s-v \033[0m\$'

Notou a diferença das cores? Vamos tentar com negrito (lembre-se, depende de como as cores foram configuradas no ~/.Xdefaults):

    PS1='\033[31;1m\h@\u, \033[33;1m \s-v, \033[0m\$ '

IMPORTANTE: Quando usamos uma cor, ela fica em vigor até sobrescrevermos ela usando outra. No final, temos que fazer a cor voltar ao modo padrão/default. Para isso usamos a sequência de escape:

    \033[0m

Aqui está uma configuração da minha variável PS1, juntamente com mais duas linhas, pois a minha PS1 depende dessas duas outras linhas:

    shopt -s checkwinsize # For hr='=='stuff to work.
    hr='============================================================================================================================================================='
    PS1='${hr::COLUMNS}\r\n\[\e[1;32m\]\s-\v, \[\e[0;32m\]\h@\u, \d \t \n\$PWD=\[\e[1;36m\]"\w" \[\e[1;37m\] \n\$ \[\e[1;37m\]'

Quem quiser tirar umas ideais, aqui estão minhas config filesno github.http://snipt.net/FernandoBasso/my-bashrc-dec-26-2011

Como eu disse no início, a intenção é mostrar a relação Xdefaults vs Escape Sequences. Tem vários tutoriais na web que tratam exclusivamente do prompt do bash. No entanto, nunca vi nenhum documento ou tutorial mencionar essa relação. Sem saber disso, ficamos configurando cores às cegas…

Descobri essa questão da relação Xdefaults/Escape Sequences perguntando no fórum do arch (em inglês), depois de levar as tradicionais broncas “vai ler no wiki”, ou “RTFM”. Ou seja, o pessoal adora assumir que os ‘aprendizes’ não gostam de ler e querem respostas prontas. PS: eu tinha lido metade da web tentando aprender mais sobre isso, e no wiki do arch também não menciona isso. :)

May the force be with you. Always.

Expressões Regulares no BASH – Parte 2

Posted in Bash by Fernando Basso on 25 de dezembro de 2011

BASH – Expressões Regulares – Parte 2

Sunday, 10:47 – December 25 – 2011

  1. Extrair Nome do Script ou o Path para o Script
  2. Verificando por Sub-Strings
  3. Substituições Básicas
  4. Remover do início da string
  5. Remover do fim da string

Dando continuação aos exemplos do primeiro tutorial sobre expressões no
bash, vamos a mais alguns exemplos diversos, que basicamente usam o que já
aprendemos anteriormente.

Extrair Nome do Script ou o Path para o Script

Sabemos que no linux os caminhos de diretórios são compostos pelos nomes
dos diretórios separados pela barra (/). Em muitos dos nossos próximos
exemplos, a barra não será usada como delimitador, mas como o próprio
elemento que queremos encontrar. Tenha isso em mente enquanto estuda os
próximos exemplos.

A variável “$0” é interna do bash, e ela mostra o nome do script.
Se executamos o script do diretório onde ele está, tudo bem, o output
mostrará o nome do script normalmente.

echo "$0"

É lógico que a variável $0 só fará sentido se utilizada
dentro de um script. Para testar pela linha de comando podemos simular
criando uma variável que contém um path (caminho) qualquer e usar a essa
variável em vez de $0:

var="/usr/local/bin/my_script"

Continuando o assunto, se o script está em /usr/local/bin/
por exemplo, então $0 vai mostrar o caminho completo do arquivo, e não
apenas o nome dele. A solução é deletar a parte que não queremos.

echo "${0##*/}"

NOTE que agora o / não é mais o delimitador. Ele é o próprio
caractere que queremos encontrar. Suponha que o script se chama
my_script, então o caminho completo será
/usr/local/bin/my_script. Em português ficaria “mostre o
conteúdo da variável $0, e delete tudo (*) até a ultima barra possível (/).
Restará só o nome final: my_script

.

Por outro lado, se queremos mostrar somente o caminho, sem o nome do
arquivo propriamente dito, temos que deletar de trás pra frente, usando o
'%' ou o '%%'.

echo "${0%%/*}"

Em português, “do final da string (%%), delete tudo (*) até encontrar a
barra (/). Sei que é estranho, por que mesmo sendo de trás pra frente, o
‘%%’ continua logo após a variável, como é o caso do ‘#’ ou ‘##’. O jeito é
acostumar, pois é assim mesmo.

Os créditos do próximo exemplo vão para mywiki.woolege.org. A
única coisa que fiz foi tentar explicar de uma maneira um pouco
diferente.

Digamos que não queremos apenas o nome final, mas as duas ultimas partes.
Bom, vamos pensar um pouco por vez. Primeiro, pegamos as partes que não
queremos, e salvamos em uma variável. Antes vamos testar. Vamos ver se a
expressão está realmente mostrando somente a parte que não queremos:

echo "${var%/*/*}"

Deleta do final até a primeira barra (/*) e deleta mais uma vez até a
próxima barra (/*). Por isso usamos /*/*. Agora sim, assine
essa regexp na variável tmp. Veja que executando o
echo, acima na verdade a espressão está deletando as duas ultimas
partes. Não tem problema, desde que salvemos essa expressão na variável.

tmp="${var%/*/*}"

Para se certificar de que a expressão está correta, vamos ver o que foi
salvo na var tmp:

echo "$tmp"

tmp agora possui '/usr/local'. Vamos então
deletar do início da string, todo o conteúdo que está em
tmp:

echo "${var#$tmp}"

É o mesmo que:

echo "${var#/usr/local/}"

Ou seja, deleta '/usr/local' deixando somente o final que
queriamos '/bin/my_script'. Faça você mesmo várias vezes e
invente exemplos próprios parecidos com esse até acostumar.

Mais um exemplo:

var="nada importante <jackpot> ... não interessa"

Agora, por algum motivo, queremos ficar somente com jackpot:

tmp="${var##*<}" # Remove do início até o <.
echo "${tmp%>*}" # Remove do > até o fim da string.

Pronto, só nos restou o que estava entre < e >.

Mais um exemplo:

      var="Isto é 'melhor' que aquilo."
      tmp="${var#*\'}" # Temos que escapar a aspa simples (\').
      echo "${tmp%\'*}" # Sobra apenas "melhor" (sem as apas).
    

Voltar


Trabalhando Com Posições Fixas – Ranges

Se sabemos quantos caracteres à direita ou a esquerda queremos, fica muito fácil:

var="ABCDEFGHIJ"

Mostramos somente os dois primeiros caracteres, ou seja, do zero ao dois:

echo "${var:0:2}"

Mostrar as últimas três posições, ou seja, da posição 7 a posição 10:

echo "${var:7:10}"

O mesmo pode ser conseguido com:

echo "${var:(-3)}"

Tenha cuidado com a sintaxe.

Em construção…

Expressões Regulares no BASH – Parte 1

Posted in Bash by Fernando Basso on 24 de dezembro de 2011

BASH – Expressões Regulares

Saturday, 10:33 – December 24 – 2011

  1. Introdução
  2. Verificando por Sub-Strings
  3. Substituições Básicas
  4. Remover do início da string
  5. Remover do fim da string

Introdução

Estes exemplos podem ser digitados diretamente na linha de comando, ou
então colocados em em arquivo. Não vou explicar isso detalhadamente agora, mas
um escript bash pode ser algo como esse exemplo:

  #!/usr/bin/env bash

  # Descomente a próxima linha para um output mais verbose.
  #set -xv

  var="May the force be with you. Always! - Master Yoda."
  echo "$var"

  if [[ -z "$var" ]]; then
      echo "A string é vazia."
  else
      echo "A string não é vazia."
  fi # Fim do 'if'.

  # Script termina aqui.

Com o terminal na pasta onde está o script, execute este comando para
rodar o script:

bash nome_do_script

Vamos criar uma variável contendo uma string. Essa variável/string
será usada nos exemplos.

var="May the force be with you. Always! - Master Yoda."

Mostrar quantos caracteres uma string possui.

echo "${#var}"

Voltar


Verificando por Sub-Strings

Colocamos a sub-string desejada entre ‘*’ (o chamado glob). Vamos
verificar se a string contém a sub-string ama:

#!/usr/bin/env bash
var="programador"
if [[ "$var" = *"ama"* ]]; then
    echo "<$var> contém a substring <ama>."
else
    echo "<$var> não contém a substring <ama>."
fi

Colocando a sub-string e uma variável, o código ficaria assim:

#!/usr/bin/env bash
var="programador"
substr="ama"
if [[ "$var" = *"$substr"* ]]; then
    echo "<$var> contém a substring <$substr>."
else
    echo "<$var> não contém a substring <$substr>."
fi

Voltar


Substuições Básicas

Usamos a barra (/) como delimitador.

Substituir ‘e’ por ‘E’. Somente a primeira ocorrência:

echo "${var/e/E}"

Para mudar todas as ocorrências de ‘e’ para ‘E’, usamos a barra duas vezes.
Dizemos que substitui globalmente.

echo "${var//e/E}"

Para efeito de ilustração, suponhamos que queremos substituir o ‘e’
mais os próximos dois caracteres, não importa quais sejam, por 1, 2 e 3
respectivamente:

echo "${var//e??/123}"

Substitui o ‘!’ por um ponto final ‘.’. Precisamos escapar o
ponto de exclamação pois ele é um caractere especial no bash.

echo "${var/\!/.}" # O . não é um metacaractere no bash. 

Subsituir spaços em branco por underscores – globalmente.

echo "${var// /_}"

Substituir . por …:

echo "${var//./...}"

Voltar


Remover do Início da String

Para remover parte do início de uma string, não usamos mais o delimitador (/).
Usamos apenas o ‘#’ ou ‘##’. Vamos aos exemplos.

Remover do início até o primeiro espaço. Um único # é non-greedy (não
ganancioso/guloso).

echo "${var#* }"

Explicando: o # busca pelo início, o * é tudo, e o espaço em branco é o
que queremos encontrar. Então, em português ficaria algo como “do início da string (#),
tudo o que for possível (*), até o primeiro espaço em branco que encontrar ( )”.

Remove do início até o último espaço em branco possível. ## é
greedy.

echo "${var##* }"

NOTE que o glob vai ANTES do item que queremos encontrar. No
exemplo, o * vem antes do espaço em branco.

Parar antes do ponto, ou seja, não incluir o ponto.

echo "${var##*([!.])}"

# ! é o operador de negação ou “NOT”.

Remove tudo, do início até o hífen (-).

echo "${var#*-}"

Remove do início até o espaço que vem após o hífen.

echo "${var#*- }"

Colocando em português, “do início (#), tudo (*),continua até o hífen (-), e inclui o espaço em branco ( )”.

Voltar


Remover do Final da String

var="May the force be with you. Always! - Master Yoda."

Agora procuramos para trás. Por isso, o * vai do lado oposto do que
vinhamos usando até agora e o operador ‘#’ muda para ‘%’.
Pra frente: “${var#*-}”
Pra trás: “${var%-*}”
– é o que queremos encontrar. É importante observar que agora a expressão
começa e ser procurada do fim do string e vai “caminhando” até o início

Remove do fim até o primeiro espaço – contando de trás pra frente. Ou
seja, o último contando do início.

echo "${var% *}"

Remove do final até o último espaço – contanto de trás pra frente. Ou
seja, o primeiro contando normalmente.

echo "${var%% *}"

Remove do fim até o hífen

echo "${var%-*}"

Remove do fim até o primeiro ‘ç’ que encontrar:

echo "${var%ç*}"

Se o caractere que queremos encontrar ocorre mais de uma vez na string,
e queremos encontrar justamente a ocorrência dele que está o mais distante
possível do final da string, usamos ‘%%’ em vez de ‘%’. O ‘e’ mais distante
do final da string nesse caso está na palavra ‘Que’ bem no início. Veja
como ficaria o código:

echo "${var%%e*}"

Voltar


A maior parte do que postei aqui eu aprendi no site
wooledge.org – um excelente site
sobre shell scripting com o bash. O que não aprendi lá aprendi lendo na web, conversando em IRCs, forums, e nos –help e man (que confesso serem
difíceis de entender as vezes).

Por enquanto é isso. Teremos mais exemplos em futuros posts.

Tagged with: , , ,