Filtrar linhas por um padrão sem linha de comandos
Publicado a 07/08/2026 · 11 min de leitura · Ferramentas de texto e idioma
Daniel Okonkwo — Programador front-end e redator de Tecnologia na Allin
Desempenho web · Formatos de ficheiro
Verificado a partir de 3 fontes
O filter-lines divide o seu texto pelas quebras de linha, testa em cada linha a presença de uma subcadeia, e mantém-na ou descarta-a. A comparação é um includes de string sobre um termo literal: não há motor de expressões regulares por trás da caixa. Escrever ^ERROR num registo não devolveu nada; ERROR|WARN também não; [a-z]+ também não. Cada um produziu um painel de saída vazio, sem mensagem de erro e sem aviso de que o padrão fora lido literalmente, e é esse o comportamento a conhecer antes de começar. O contrário também é verdade e é mais tranquilizador: uma expressão regular inválida é inofensiva aqui, porque não é uma expressão regular. Escrever um simples parêntese de abertura manteve a linha que contém um, exatamente como quereria. «Ignorar maiúsculas» está ativo por omissão: filtrar por apple manteve a linha APPLE juice tanto quanto apple pie; o grep num terminal distingue maiúsculas por omissão e esta ferramenta não, diferença a ter presente se está habituado a uma das duas. A ação oferece «Manter linhas correspondentes» e «Remover linhas correspondentes», que correspondem a grep e grep -v. Deixar o termo vazio devolve o seu texto inalterado, e não nada. Dois detalhes dos ensaios: o modo remover mantém as linhas vazias, porque uma linha vazia não contém o seu termo, portanto um registo filtrado volta com os buracos deixados pelas linhas retiradas; e toda a saída é unida com quebras simples, pelo que um ficheiro Windows perde os retornos de carro pelo caminho.
Isto é o grep para quem não usa grep, com uma diferença importante: a procura é uma subcadeia literal, pelo que uma expressão regular a sério devolve uma caixa vazia e nenhum erro. Cada afirmação foi verificada executando a ferramenta.
O que faz o grep, e que metade está aqui
O grep lê um texto linha a linha, confronta cada linha com um padrão, e escreve as linhas que correspondem. A especificação POSIX define-o assim e define o padrão como uma expressão regular: uma pequena linguagem em que um acento circunflexo significa «início de linha», uma barra vertical «ou então», os parênteses retos «qualquer um destes carateres» e um mais «uma ou mais vezes o que vem antes». A opção de inversão vira o teste e imprime as linhas que não correspondem. A ideia tem uns quarenta anos e continua a ser a via mais rápida para responder a uma pergunta sobre um ficheiro de registo.
O filter-lines implementa o ciclo e a opção de inversão, e para por aí. A linguagem de padrões não está implementada, e sobretudo não está implementada pela metade: o termo que escreve é comparado como uma sequência de carateres, inteira e inalterada. É um desenho legítimo para uma caixa numa página web — a maioria de quem filtra uma lista quer as linhas que contêm a palavra fatura, não uma gramática — mas significa que as duas ferramentas recebem a mesma entrada e dão respostas diferentes, e a que se engana nunca o diz.
A caixa vazia, e porque está vazia
Passaram-se três padrões pelo mesmo registo de sete linhas. ^ERROR não devolveu nada, embora duas linhas comecem por ERROR, porque nenhuma linha contém um acento circunflexo literal seguido das letras E, R, R, O, R. ERROR|WARN não devolveu nada, embora o registo tenha um de cada, porque nenhuma linha contém uma barra vertical literal entre essas duas palavras. [a-z]+ não devolveu nada, pela mesma razão: nenhuma linha contém um parêntese reto. Em todos os casos o painel de saída estava simplesmente vazio. Nada foi destacado, nada foi assinalado e nada sugeriu que o termo tivesse sido lido de forma diferente da pretendida.
É este o modo de falha que importa, e é o inverso do que a expressão «regex inválida» sugeriria. Um padrão malformado é o caso seguro. Escrever um simples parêntese de abertura — o que faria um motor de expressões regulares lançar um erro de grupo por fechar — manteve a linha que contém um parêntese e devolveu-a. O mesmo com um ponto solto, que na linguagem das expressões regulares significa «qualquer carácter» e aqui significa «um ponto»: sobre uma lista com a.b e aXb devolveu apenas a.b. Se se apanhar a escrever sintaxe de expressão regular nesta caixa, o reflexo a construir é olhar para a saída e perguntar-se se um resultado vazio é plausível, porque a ferramenta não o perguntará por si.
Caixa, acentos e o espaço que não queria escrever
«Ignorar maiúsculas» está ativo de fábrica e põe em minúsculas tanto a linha como o termo antes de comparar. Filtrar uma lista de cinco frutas por apple manteve apple pie, APPLE juice e pineapple tart; desligar o interruptor descartou APPLE juice e manteve as outras duas. A linha do pineapple lembra que isto é um teste de subcadeia e não de palavra: apple está dentro de pineapple, portanto a linha corresponde, e não há opção de «palavra inteira» que o impeça. Se precisa de fronteiras de palavra, acrescente os espaços à volta do seu termo e aceite que lhe escapará a palavra no início ou no fim de uma linha.
Das mesmas provas saíram duas armadilhas menores. Um espaço no início do termo faz parte do termo: filtrar a mesma lista por «espaço + apple» não devolveu nada, porque nenhuma linha tem um espaço antes dessa palavra na posição testada. E os acentos seguem a regra do artigo sobre duplicados: um termo cuja letra acentuada se escreve como letra mais marca combinante não encontrou nada numa lista cuja letra acentuada é um único ponto de código, embora as duas pareçam idênticas na caixa de procura. Ambas voltam à mesma disciplina: o que escreveu é comparado exatamente como escreveu, incluindo as partes que não vê.
O modo remover deixa buracos
Mude a ação para «Remover linhas correspondentes» e a ferramenta descarta cada linha que contém o seu termo e mantém tudo o resto — incluindo as linhas vazias, porque uma linha vazia não contém o seu termo. Passe-o por um registo com uma linha vazia entre duas entradas e a linha vazia continua lá depois. Não é um defeito, é a leitura honesta da instrução, mas o resultado raramente se parece com o esperado, e um ficheiro filtrado com uma dúzia de buracos órfãos é incómodo de ler. O remédio é mais um passo: passe o remove-blank-lines pela saída.
Mais um comportamento em que confiar: um termo vazio devolve o seu texto inalterado, não um resultado vazio. Parece óbvio, mas a leitura contrária — sem termo, nada corresponde, nada sai — seria igualmente defensável e esvaziaria em silêncio a sua entrada sempre que limpasse o campo para escrever outra procura. A ferramenta escolhe o ramo mais seguro, e isso foi verificado: com o campo vazio, voltaram as cinco linhas da lista de teste.
Que fazer quando precisa mesmo de um padrão
A maioria das perguntas de padrão pode ser reescrita como perguntas de subcadeia. «Linhas que começam por um código» passa a «linhas que contêm esse código», mais frouxo mas em geral suficiente num registo onde o código só aparece no início de qualquer modo. «Qualquer uma de duas palavras» passa a duas passagens — filtre pela primeira, anote o resultado, filtre o original pela segunda — porque não há alternância. «Um intervalo de carateres» costuma passar a várias passagens, ou diretamente a outra ferramenta. Quando a resposta precisa mesmo de uma gramática, o conselho honesto é que uma caixa de texto num navegador é o instrumento errado, e o certo é um terminal ou um editor de texto com procura por expressão regular.
Uma ressalva sobre a ferramenta irmã. O find-and-replace, neste mesmo site, também recebe um termo literal: faz escape a cada carácter com significado especial antes de construir o seu padrão, o que foi lido no código e confirmado. Portanto, se esperava usá-lo para simular um filtro por expressão regular, não pode. As duas ferramentas são coerentes entre si, essa é a boa notícia; nenhuma das duas é o grep, essa é a notícia de que precisava antes de começar.
| Termo escrito | O que volta | Porquê |
|---|---|---|
| apple, «Ignorar maiúsculas» ativo (por omissão) | apple pie, APPLE juice e pineapple tart | Ambos os lados são postos em minúsculas, e o teste é de subcadeia, não de palavra inteira |
| apple, «Ignorar maiúsculas» desligado | apenas apple pie e pineapple tart | APPLE juice já não contém os carateres exatos escritos |
| ^ERROR sobre um registo cujas duas primeiras linhas começam por ERROR | Saída vazia, nenhuma mensagem de erro | Nenhuma linha contém um acento circunflexo literal seguido dessas cinco letras |
| ERROR|WARN sobre o mesmo registo | Saída vazia | Não há alternância; a barra vertical é apenas um carácter a procurar |
| Um simples parêntese de abertura | A linha que contém um parêntese — funciona | Uma expressão regular inválida é o caso seguro, porque nenhuma é compilada |
| Um ponto solto, sobre uma lista com a.b e aXb | apenas a.b | O ponto corresponde a um ponto, não a qualquer carácter |
| Um campo «Contém» vazio | O texto inteiro, inalterado | A ferramenta sai logo em vez de filtrar tudo |
| Qualquer termo, no modo «Remover linhas correspondentes», sobre um texto com linhas vazias | As linhas vazias sobrevivem | Uma linha vazia não contém o termo, portanto não é uma correspondência a remover |
Perguntas frequentes
- Posso usar uma expressão regular no campo «Contém»?
- Não. O termo é comparado literalmente, carácter a carácter, sem qualquer linguagem de padrões por trás. Isto foi verificado com três padrões correntes — uma âncora de início de linha, uma alternância e uma classe de carateres — e os três devolveram um painel de saída vazio sem mensagem. O comportamento a interiorizar é que aqui uma resposta errada se parece exatamente com uma resposta correta de «nada correspondeu», portanto trate um resultado vazio como uma pergunta e não como um facto: reescreva o termo sem os carateres de sintaxe e veja se aparecem linhas.
- Como fico só com as linhas que começam por alguma coisa?
- Aqui não pode pedir «início de linha», porque não há âncora. Na prática a versão de subcadeia costuma bastar: filtre pelo código ou prefixo em si, e aceite as linhas que o contenham noutro sítio. Se isso é aceitável depende dos seus dados, e pode descobri-lo barato: filtre uma vez, depois passe o mesmo termo em modo remover e olhe para o que saiu. Se o monte removido não contiver nada que quisesse, a versão frouxa servia. Se precisa mesmo da âncora, um editor de texto com procura por expressão regular é a ferramenta.
- O filtro distingue maiúsculas?
- Por omissão não. «Ignorar maiúsculas» está ativo ao carregar a página, o contrário da definição por omissão do grep e o contrário do que espera quem usa o terminal a sério. Desligue-o no mesmo painel se precisa da distinção: filtrar uma lista de frutas por apple com o interruptor ativo manteve uma linha APPLE juice, e desligá-lo descartou essa linha mantendo as duas em minúsculas. A dobra é a simples, independente da língua: trata bem as maiúsculas acentuadas mas não faz nada de especial para uma língua concreta.
- Porque é que a minha saída filtrada tem buracos?
- Porque usou «Remover linhas correspondentes» e o seu texto tinha linhas vazias. Uma linha vazia não contém o seu termo, portanto a ferramenta mantém-na, e ela fica exatamente onde estava — agora rodeada do espaço que as linhas retiradas ocupavam. Passar o remove-blank-lines pelo resultado fecha-as todas de uma vez. Se encadeia vários filtros, faça a limpeza de linhas vazias uma só vez no fim e não a seguir a cada passo, porque cada passagem de remoção abrirá buracos novos.
- A ferramenta diz-me quantas linhas corresponderam?
- Não é mostrada contagem alguma; obtém as linhas correspondentes e nada mais. Se precisa do número, o caminho mais curto é passar o resultado por um contador de linhas, ou usar o count-occurrences sobre o texto original com o mesmo termo — tendo em conta que conta ocorrências e que uma mesma linha pode conter o seu termo duas vezes, pelo que os dois números podem diferir legitimamente. Se o que quer é a contagem e não as linhas, o count-occurrences é o melhor ponto de partida.
Artigos que podem interessar-lhe
Todos os guias →Ferramentas relacionadas
Tudo o que se segue descreve o que estas ferramentas fazem hoje, verificado executando as suas próprias transformações sobre as entradas exatas reproduzidas em cada artigo, e não o que uma norma obrigue uma ferramenta de texto a fazer. O tratamento do texto linha a linha não tem autoridade única: o que conta como espaço, se duas linhas acentuadas são ou não a mesma linha, e onde termina um URL dentro de uma frase são decididos de forma diferente por cada programa onde colar texto. Quando uma ferramenta erra num caso, isso é dito com franqueza em vez de contornado. Antes de passar qualquer disto por uma lista que não possa reexportar, passe por uma cópia e compare o número de linhas nas duas pontas.
Fontes
Detetaste um erro neste artigo?