Filtrando textos no Bash

Curso de Bash

Seção do curso de Bash sobre filtragem de texto em seções com cut e grep.

Conteúdo

  1. Filtrando colunas com cut
  2. Filtrando linhas com grep
  3. Exercícios

Filtrando colunas com cut

cut divide o texto em colunas e exibe as colunas especificadas. Por padrão, o delimitador de colunas é o caractere tabulação.

Arquivo colunas criado com tabulação separando letras na mesma linha e ; separando números.

printf "A\tO\tY\nB\tP\tZ\n0;1;2;3\n" > colunas
cat colunas
A   O   Y
B   P   Z
0;1;2;3

A opção -f permite especificar as colunas que serão exibidas. Linhas sem o delimitador serão sempre exibidas (como 0;1;2;3 abaixo).

cut -f 2 colunas
O
P
0;1;2;3

Para especificar mais de uma coluna, separe os números com , e não use espaço entre eles.

cut -f 1,3 colunas
A   Y
B   Z
0;1;2;3

Para remover as linhas sem delimitador, insira a opção -s.

Abaixo apenas as linhas com tabulação (delimitador padrão) são elegíveis para a saída.

cut -sf 1,3 colunas
A   Y
B   Z

A opção -d permite especificar outro delimitador.

Abaixo, ; precisa ser envolvido em '' por ser um operador de controle (não confundir com caractere de controle), caso não fosse seria interpretado como fim do comando (assunto abordado em futuro capítulo). -s remove as linhas sem o novo delimitador especificado ;.

cut -s -d ';' -f 2,3 colunas
1;2

A opção --output-delimiter permite substituir ou remover o delimitador da saída.

No comando abaixo, espaço substitui ; como delimitador.

cut -sd ';' -f 2,3 --output-delimiter ' ' colunas
1 2

Alternativamente, cut pode dividir as colunas por caracteres e exibi-los em determinadas posições de cada linha com a opção -c.

cut -c 1,3,5 colunas
AOY
BPZ
012

Filtrando linhas com grep

grep exibe as linhas que correspondem a determinados padrões.

grep recebe dois ou mais argumentos, o primeiro sendo o padrão que será comparado às linhas dos arquivos informados do segundo argumento em diante.

Arquivo filtrando será utilizado nos exemplos a seguir.

echo 'ABCDEFGHIJKLMNOPQRSTUVWXYZ
maiúsculas acima
e minúsculas abaixo
abcdefghijklmnopqrstuvwxyz
0123456789
0123456789ABCDEFabcdef
!"#$%&()*+,-./:;<=>?@[\]^_`{|}~' > filtrando

Padrão é um conjunto de caracteres que definem o que será buscado no texto. Os caracteres do padrão podem definir comparações literais (como ter o padrão ABC e buscar por linhas que contenham a sequência ABC), podem representar um conjunto de caracteres (o padrão [0-9] corresponderia aos dígitos de 0 até 9) ou até mesmo um formato de como um trecho de texto é disposto (o padrão ^0.*f$ busca por linhas que iniciam com 0, tem zero ou mais caracteres quaisquer e encerram com a letra f).

⚠️ grep é case sensitive (sensível à capitalização). O padrão z é diferente de Z.

No comando abaixo, apenas as linhas que contém ao menos uma ocorrência da letra f serão exibidas.

grep f filtrando
abcdefghijklmnopqrstuvwxyz
0123456789ABCDEFabcdef

O padrão também pode ser uma sequência de caracteres. Como abaixo onde grep exibe apenas as linhas que contém a sequência fg.

grep fg filtrando
abcdefghijklmnopqrstuvwxyz

Expressões de colchete são listas de caracteres que são comparados ao texto como se fossem um só caractere.

A expressão de colchete [fg] filtra as linhas que contenham f ou g.

grep [fg] filtrando
abcdefghijklmnopqrstuvwxyz
0123456789ABCDEFabcdef

F[aG] exibe as linhas que contenham a sequência de F seguido por a ou G.

grep F[aG] filtrando
ABCDEFGHIJKLMNOPQRSTUVWXYZ
0123456789ABCDEFabcdef

m[ia][ni]úsculas exibe as linhas que contenham a sequência de m seguido por i ou a seguido por n ou i e então úsculas.

grep m[ia][ni]úsculas filtrando
maiúsculas acima
e minúsculas abaixo

As expressões de colchete podem conter intervalos como [2-4], que seria equivalente à [234].

grep [2-4] filtrando
0123456789
0123456789ABCDEFabcdef

Intervalos com letras também são possíveis. [f-i] equivale à [fghi].

grep [f-i] filtrando
maiúsculas
minúsculas
abcdefghijklmnopqrstuvwxyz
0123456789ABCDEFabcdef

. representa um caractere qualquer.

grep . filtrando
maiúsculas
ABCDEFGHIJKLMNOPQRSTUVWXYZ
minúsculas
abcdefghijklmnopqrstuvwxyz
0123456789
0123456789ABCDEFabcdef
!"#$%&()*+,-./:;<=>?@[\]^_`{|}~

.A representa a sequência de um caractere qualquer seguido por A.

grep .A filtrando
0123456789ABCDEFabcdef

.m.. é correspondido por um caractere qualquer seguido de m seguido de dois caracteres quaisquer.

grep .m.. filtrando
e minúsculas abaixo
abcdefghijklmnopqrstuvwxyz

^ representa o início de linha. Abaixo grep exibe as linhas que começam com 01.

grep ^01 filtrando
0123456789
0123456789ABCDEFabcdef

$ representa o fim de linha. grep exibe as linhas que terminam com ef.

grep ef$ filtrando
0123456789ABCDEFabcdef

-c exibe a quantidade de linhas que correspondem ao padrão.

grep -c ef$ filtrando
1

-n exibe o número da linha antes de cada linha correspondente.

grep -n 12 filtrando
3:0123456789
4:0123456789ABCDEFabcdef

-o exibe apenas a sequência de caracteres correspondentes ao padrão. Os caracteres que antecedem ou sucedem as sequências são descartados da saída.

grep -o 12 filtrando
12
12

Classe de caracteres

Classe de caracteres é uma forma concisa de representar um conjunto de caracteres.

  • [:digit:]: dígitos decimais, [0-9];
  • [:xdigit:]: dígitos hexadecimais, [0-9a-fA-F];
  • [:alpha:]: letras, [A-Za-z];
  • [:upper:]: letras maiúsculas, [A-Z];
  • [:lower:]: letras minúsculas, [a-z];
  • [:alnum:]: letras e dígitos, [0-9A-Za-z] ou [[:alpha:][:digit:]];
  • [:punct:]: pontuações;
  • [:graph:]: letras, números e pontuações, [[:alnum:][:punct:]];
  • [:print:]: letras, números, pontuações e espaço, [[:alnum:][:punct:]" "];
  • [:blank:]: espaço e tabulação;
  • [:space:]: espaço, tabulação, novalinha e outros caracteres de espaço;
  • [:cntrl:]: caracteres de controle .

As classes de caracteres devem ser informadas dentro da expressão de colchete. A expressão de colchete deve estar envolta à '' ou "".

grep "[[:upper:]]" filtrando
ABCDEFGHIJKLMNOPQRSTUVWXYZ
0123456789ABCDEFabcdef

Todas as linhas que contenham algum caractere de espaço ou algum dígito.

grep "[[:space:][:digit:]]" filtrando
maiúsculas acima
e minúsculas abaixo
0123456789
0123456789ABCDEFabcdef

s[[:space:]]a corresponde à toda sequência iniciando com s seguido por algum caractere de espaço seguido por a.

grep "s[[:space:]]a" filtrando
maiúsculas acima
e minúsculas abaixo

Se ^ é o primeiro caractere na expressão de colchete, o padrão será correspondido por todos os outros caracteres que não aparecem dentro da expressão.

Todas as linhas cujos caracteres não sejam letras, dígitos ou pontuações serão exibidos com o padrão [^[:graph:]], ou seja, apenas as linhas contendo espaço aparecem.

grep "[^[:graph:]]" filtrando
maiúsculas acima
e minúsculas abaixo

Abaixo todas as linhas que contenham caracteres que não sejam números ou letras ([:alnum:]) ou espaços ([:space:]). Restando então as linhas que contenham caracteres de pontuação.

grep "[^[:alnum:][:space:]]" filtrando
!"#$%&()*+,-./:;<=>?@[\]^_`{|}~

^[^0] será correspondido por linhas que não iniciem com 0.

grep "^[^0]" filtrando
ABCDEFGHIJKLMNOPQRSTUVWXYZ
maiúsculas acima
e minúsculas abaixo
abcdefghijklmnopqrstuvwxyz
!"#$%&()*+,-./:;<=>?@[\]^_`{|}~

^[^0a-z] será correspondido por linhas que não iniciem com 0 ou letras minúsculas.

grep "^[^0a-z]" filtrando
ABCDEFGHIJKLMNOPQRSTUVWXYZ
!"#$%&()*+,-./:;<=>?@[\]^_`{|}~

Repetições

Quantificadores permitem que uma sequência de caracteres sejam especificadas sucintamente no padrão. P. ex., ao invés do padrão TTTTTTTT poderíamos especificar T{8}.

A opção -E habilita as Expressões Regulares Estendidas o que significa que os caracteres ? + { | ( ) tem um significado especial e são interpretados.

O arquivo repeticoes será utilizado nesta seção.

printf 'arara
casas
gesso
jararaca
jarro
mera
reparar
serra
tear
XIX
XXVI
XXXIX' > repeticoes

{n}: o caractere que o precede será correspondido se encontrado exatamente n vezes em sequência.

P. ex., r{2} representa o mesmo padrão que rr.

grep -E "r{2}" repeticoes
jarro
serra

O padrão ar{2} representa arr.

grep -E "ar{2}" repeticoes
jarro

(), operador de agrupamento, permite delimitar uma sequência de forma que ela é interpretada como um só caractere.

O padrão (ar){2} é o mesmo que o padrão arar.

grep -E "(ar){2}" repeticoes
arara
jararaca
reparar

p(ar){2} equivale ao padrão parar.

grep -E "p(ar){2}" repeticoes
reparar

j(ar){2}a equivale à jarara.

grep -E "j(ar){2}a" repeticoes
jararaca

O caractere que precede {n,} será correspondido se encontrado pelo menos n vezes em sequência.

grep -E "s{1,}" repeticoes
casas
gesso
serra

s{1,}e equivale à se, sse, ssse etc.

grep -E "s{1,}e" repeticoes
serra

O caractere que precede {n,m} será correspondido se encontrado no mínimo n vezes e no máximo m vezes em sequência.

O padrão X{2,3} seria o mesmo que XX e XXX.

grep -E "X{2,3}" repeticoes
XXVI
XXXIX

XX{2,3}I seria XXI e XXXI.

grep -E "X{2,3}I" repeticoes
XXXIX

⚠️ Quando n em {n,m} ou {n,} é 0 o padrão também é correspondido quando o caractere não ocorre nas linhas comparadas. É utilizado quando o caractere a ser correspondido é opcional.

s{0,2}o seria equivalente à o, so e sso.

grep -E "s{0,2}o" repeticoes
jarro
gesso

X{1,2}I{0,1} seria XI, XVI, XXI e XXVI.

grep -E "X{1,2}V{0,1}I" repeticoes
XXXIX
XIX
XXVI

{0,1} pode ser substituído por ?.

er?a equivale à era e ea.

grep -E  "er?a" repeticoes
mera
tear

{1,} pode ser substituído por +.

r.+r equivale à qualquer sequência que inicia com r seguido de um ou mais caracteres quaisquer e termina em r.

grep -E  "r.+r" repeticoes
arara
jararaca
reparar

{0,} pode ser substituído por *.

r.+r equivale à qualquer sequência que inicia com r seguido de nenhum, um ou mais caracteres quaisquer e termina em r.

grep -E  "r.*r" repeticoes
arara
reparar
serra
jararaca
jarro

|, operador de alternância, permite que o caractere buscado seja correpondente a qualquer uma das duas sequências especificadas no padrão. ser|mer seria o padrão ser e mer.

grep -E "ser|mer" repeticoes
mera
serra

Alternância pode ser inserida em um agrupamento, como abaixo em que (s|m)er é equivalente à ser e mer.

grep -E "(s|m)er" repeticoes
mera
serra

Controle de correspondência

Opções que alteram a correspondência com o padrão.

Para ignorar a caixa da letra (se é maiúscula ou minúscula), utilize a opção -i. O padrão abaixo corresponde à F ou f.

grep -i f filtrando
ABCDEFGHIJKLMNOPQRSTUVWXYZ
abcdefghijklmnopqrstuvwxyz
0123456789ABCDEFabcdef

A opção -e permite especificar múltiplos padrões. As linhas exibidas deverão corresponder a um dos dois padrões.

São exibidas, abaixo, as linhas que começam com 0 ou que terminam com z.

grep -e ^0 -e z$ filtrando
abcdefghijklmnopqrstuvwxyz
0123456789
0123456789ABCDEFabcdef

-v inverte a correspondência. Exibe apenas as linhas não correspondentes ao padrão.

As linhas que não contêm letras são exibidas abaixo.

grep -v "[[:alpha:]]" filtrando
0123456789
!"#$%&()*+,-./:;<=>?@[\]^_`{|}~

Sem a opção -v temos o complemento da saída anterior.

grep "[[:alpha:]]" filtrando
ABCDEFGHIJKLMNOPQRSTUVWXYZ
maiúsculas acima
e minúsculas abaixo
abcdefghijklmnopqrstuvwxyz
0123456789ABCDEFabcdef

-w exibe as linhas em que ao menos uma das palavras tenha todos os seus caracteres correspondidos ao padrão.

grep -w e filtrando
e minúsculas abaixo

Sem -w teríamos:

grep e filtrando
e minúsculas abaixo
abcdefghijklmnopqrstuvwxyz
0123456789ABCDEFabcdef

-x exibe apenas as linhas em que todos os seus caracteres correspondem ao padrão.

grep -x 0.*9 filtrando
0123456789

Sem a opção -x teríamos uma outra correspondência.

grep 0.*9 filtrando
0123456789
0123456789ABCDEFabcdef

Exercícios

Escolha as linhas correspondentes ao padrão

sso
sso$
^.sso
ss.s
[aiu]
[g-p]es
[g-p]es[p-s]
s[[:lower:]]s
^[^p]
^[^g-i]
^[^g-i][^s]
s{1,2}.s
es{2,}
so.+
[ou]ss?os
os.*
ss(o|a)s
sso|as
Escrito por Caio Santesso.

Comentários

  • Conteúdo dos posts, exceto onde indicado contrário, licenciado sob a licença CC BY-SA 4.0 .